diff options
| author | bors <bors@rust-lang.org> | 2025-05-15 20:20:30 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-05-15 20:20:30 +0000 |
| commit | d97326eabfc3b2c33abcb08d6bc117aefa697cb7 (patch) | |
| tree | 76f04380bbd31072d5d2acb8112abf28c9e0ecab /library/alloc/src | |
| parent | c4e05e53d19b550a358ee8b2e29ecd5a11075800 (diff) | |
| parent | 1ef7585c9ef976211b897e22fad6ae9aa2c2f415 (diff) | |
| download | rust-d97326eabfc3b2c33abcb08d6bc117aefa697cb7.tar.gz rust-d97326eabfc3b2c33abcb08d6bc117aefa697cb7.zip | |
Auto merge of #136264 - GuillaumeGomez:optimize-integers-to-string, r=Amanieu
Optimize `ToString` implementation for integers Part of https://github.com/rust-lang/rust/issues/135543. Follow-up of https://github.com/rust-lang/rust/pull/133247 and https://github.com/rust-lang/rust/pull/128204. The benchmark results are: | name| 1.87.0-nightly (3ea711f17 2025-03-09) | With this PR | diff | |-|-|-|-| | bench_i16 | 32.06 ns/iter (+/- 0.12) | 17.62 ns/iter (+/- 0.03) | -45% | | bench_i32 | 31.61 ns/iter (+/- 0.04) | 15.10 ns/iter (+/- 0.06) | -52% | | bench_i64 | 31.71 ns/iter (+/- 0.07) | 15.02 ns/iter (+/- 0.20) | -52% | | bench_i8 | 13.21 ns/iter (+/- 0.14) | 14.93 ns/iter (+/- 0.16) | +13% | | bench_u16 | 31.20 ns/iter (+/- 0.06) | 16.14 ns/iter (+/- 0.11) | -48% | | bench_u32 | 33.27 ns/iter (+/- 0.05) | 16.18 ns/iter (+/- 0.10) | -51% | | bench_u64 | 31.44 ns/iter (+/- 0.06) | 16.62 ns/iter (+/- 0.21) | -47% | | bench_u8 | 10.57 ns/iter (+/- 0.30) | 13.00 ns/iter (+/- 0.43) | +22% | More information about it in [the original comment](https://github.com/rust-lang/rust/pull/136264#discussion_r1987542954). r? `@workingjubilee`
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/string.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 4e42a5da7ea..37614a7ca45 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2826,7 +2826,54 @@ impl SpecToString for bool { } } +macro_rules! impl_to_string { + ($($signed:ident, $unsigned:ident,)*) => { + $( + #[cfg(not(no_global_oom_handling))] + #[cfg(not(feature = "optimize_for_size"))] + impl SpecToString for $signed { + #[inline] + fn spec_to_string(&self) -> String { + const SIZE: usize = $signed::MAX.ilog(10) as usize + 1; + let mut buf = [core::mem::MaybeUninit::<u8>::uninit(); SIZE]; + // Only difference between signed and unsigned are these 8 lines. + let mut out; + if *self < 0 { + out = String::with_capacity(SIZE + 1); + out.push('-'); + } else { + out = String::with_capacity(SIZE); + } + + out.push_str(self.unsigned_abs()._fmt(&mut buf)); + out + } + } + #[cfg(not(no_global_oom_handling))] + #[cfg(not(feature = "optimize_for_size"))] + impl SpecToString for $unsigned { + #[inline] + fn spec_to_string(&self) -> String { + const SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1; + let mut buf = [core::mem::MaybeUninit::<u8>::uninit(); SIZE]; + + self._fmt(&mut buf).to_string() + } + } + )* + } +} + +impl_to_string! { + i8, u8, + i16, u16, + i32, u32, + i64, u64, + isize, usize, +} + #[cfg(not(no_global_oom_handling))] +#[cfg(feature = "optimize_for_size")] impl SpecToString for u8 { #[inline] fn spec_to_string(&self) -> String { @@ -2846,6 +2893,7 @@ impl SpecToString for u8 { } #[cfg(not(no_global_oom_handling))] +#[cfg(feature = "optimize_for_size")] impl SpecToString for i8 { #[inline] fn spec_to_string(&self) -> String { |
