From cb0f543f31e913f3ac34aac4e1443d105f419c28 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 13 Nov 2018 13:54:51 +0100 Subject: [PATCH 1/2] core/benches/num: Add `from_str/from_str_radix()` benchmarks --- src/libcore/benches/num/mod.rs | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/libcore/benches/num/mod.rs b/src/libcore/benches/num/mod.rs index 55f0bdb57ec82..b57e167b05d9e 100644 --- a/src/libcore/benches/num/mod.rs +++ b/src/libcore/benches/num/mod.rs @@ -10,3 +10,108 @@ mod flt2dec; mod dec2flt; + +use test::Bencher; +use std::str::FromStr; + +const ASCII_NUMBERS: [&str; 19] = [ + "0", + "1", + "2", + "43", + "765", + "76567", + "987245987", + "-4aa32", + "1786235", + "8723095", + "f##5s", + "83638730", + "-2345", + "562aa43", + "-1", + "-0", + "abc", + "xyz", + "c0ffee", +]; + +macro_rules! from_str_bench { + ($mac:ident, $t:ty) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str(s).ok()) + .max() + }) + } + ) +} + +macro_rules! from_str_radix_bench { + ($mac:ident, $t:ty, $radix:expr) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str_radix(s, $radix).ok()) + .max() + }) + } + ) +} + +from_str_bench!(bench_u8_from_str, u8); +from_str_radix_bench!(bench_u8_from_str_radix_2, u8, 2); +from_str_radix_bench!(bench_u8_from_str_radix_10, u8, 10); +from_str_radix_bench!(bench_u8_from_str_radix_16, u8, 16); +from_str_radix_bench!(bench_u8_from_str_radix_36, u8, 36); + +from_str_bench!(bench_u16_from_str, u16); +from_str_radix_bench!(bench_u16_from_str_radix_2, u16, 2); +from_str_radix_bench!(bench_u16_from_str_radix_10, u16, 10); +from_str_radix_bench!(bench_u16_from_str_radix_16, u16, 16); +from_str_radix_bench!(bench_u16_from_str_radix_36, u16, 36); + +from_str_bench!(bench_u32_from_str, u32); +from_str_radix_bench!(bench_u32_from_str_radix_2, u32, 2); +from_str_radix_bench!(bench_u32_from_str_radix_10, u32, 10); +from_str_radix_bench!(bench_u32_from_str_radix_16, u32, 16); +from_str_radix_bench!(bench_u32_from_str_radix_36, u32, 36); + +from_str_bench!(bench_u64_from_str, u64); +from_str_radix_bench!(bench_u64_from_str_radix_2, u64, 2); +from_str_radix_bench!(bench_u64_from_str_radix_10, u64, 10); +from_str_radix_bench!(bench_u64_from_str_radix_16, u64, 16); +from_str_radix_bench!(bench_u64_from_str_radix_36, u64, 36); + +from_str_bench!(bench_i8_from_str, i8); +from_str_radix_bench!(bench_i8_from_str_radix_2, i8, 2); +from_str_radix_bench!(bench_i8_from_str_radix_10, i8, 10); +from_str_radix_bench!(bench_i8_from_str_radix_16, i8, 16); +from_str_radix_bench!(bench_i8_from_str_radix_36, i8, 36); + +from_str_bench!(bench_i16_from_str, i16); +from_str_radix_bench!(bench_i16_from_str_radix_2, i16, 2); +from_str_radix_bench!(bench_i16_from_str_radix_10, i16, 10); +from_str_radix_bench!(bench_i16_from_str_radix_16, i16, 16); +from_str_radix_bench!(bench_i16_from_str_radix_36, i16, 36); + +from_str_bench!(bench_i32_from_str, i32); +from_str_radix_bench!(bench_i32_from_str_radix_2, i32, 2); +from_str_radix_bench!(bench_i32_from_str_radix_10, i32, 10); +from_str_radix_bench!(bench_i32_from_str_radix_16, i32, 16); +from_str_radix_bench!(bench_i32_from_str_radix_36, i32, 36); + +from_str_bench!(bench_i64_from_str, i64); +from_str_radix_bench!(bench_i64_from_str_radix_2, i64, 2); +from_str_radix_bench!(bench_i64_from_str_radix_10, i64, 10); +from_str_radix_bench!(bench_i64_from_str_radix_16, i64, 16); +from_str_radix_bench!(bench_i64_from_str_radix_36, i64, 36); From f47de025ce91ce2b45fb5f204317981b410c0bff Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 15 Nov 2018 10:28:11 +0100 Subject: [PATCH 2/2] core/num: Use `from_str_radix()` method in `from_str()` This commit changes the `from_str()` implementation to use the `from_str_radix()` *method* instead of using the `from_str_radix()` *function* directly. I did not expect any performance changes from this, but running the new benchmarks shows that it seems to speed up the `from_str_radix()` benchmarks, while not affecting the `from_str()` performance. The `i16` benchmarks seem to slightly regress for some reason, though that could also be related to them running first and `test::Bencher` not using a warmup period (unlike criterion.rs). ### Benchmark Results ``` name control.txt ns/iter variable.txt ns/iter diff ns/iter diff % speedup num::bench_i16_from_str 33,408 33,646 238 0.71% x 0.99 num::bench_i16_from_str_radix_10 31,119 32,768 1,649 5.30% x 0.95 num::bench_i16_from_str_radix_16 32,198 35,726 3,528 10.96% x 0.90 num::bench_i16_from_str_radix_2 23,319 21,794 -1,525 -6.54% x 1.07 num::bench_i16_from_str_radix_36 31,440 34,217 2,777 8.83% x 0.92 num::bench_i32_from_str 33,248 33,235 -13 -0.04% x 1.00 num::bench_i32_from_str_radix_10 33,138 31,791 -1,347 -4.06% x 1.04 num::bench_i32_from_str_radix_16 37,350 35,867 -1,483 -3.97% x 1.04 num::bench_i32_from_str_radix_2 22,602 21,269 -1,333 -5.90% x 1.06 num::bench_i32_from_str_radix_36 36,946 35,550 -1,396 -3.78% x 1.04 num::bench_i64_from_str 40,238 41,167 929 2.31% x 0.98 num::bench_i64_from_str_radix_10 39,251 35,293 -3,958 -10.08% x 1.11 num::bench_i64_from_str_radix_16 40,549 36,417 -4,132 -10.19% x 1.11 num::bench_i64_from_str_radix_2 25,645 22,119 -3,526 -13.75% x 1.16 num::bench_i64_from_str_radix_36 41,253 37,102 -4,151 -10.06% x 1.11 num::bench_i8_from_str 35,448 33,067 -2,381 -6.72% x 1.07 num::bench_i8_from_str_radix_10 33,548 31,128 -2,420 -7.21% x 1.08 num::bench_i8_from_str_radix_16 34,571 32,268 -2,303 -6.66% x 1.07 num::bench_i8_from_str_radix_2 27,035 25,228 -1,807 -6.68% x 1.07 num::bench_i8_from_str_radix_36 32,983 30,924 -2,059 -6.24% x 1.07 num::bench_u16_from_str 24,972 24,995 23 0.09% x 1.00 num::bench_u16_from_str_radix_10 30,680 28,935 -1,745 -5.69% x 1.06 num::bench_u16_from_str_radix_16 33,354 31,709 -1,645 -4.93% x 1.05 num::bench_u16_from_str_radix_2 23,712 22,231 -1,481 -6.25% x 1.07 num::bench_u16_from_str_radix_36 32,593 30,699 -1,894 -5.81% x 1.06 num::bench_u32_from_str 26,377 26,373 -4 -0.02% x 1.00 num::bench_u32_from_str_radix_10 36,649 36,282 -367 -1.00% x 1.01 num::bench_u32_from_str_radix_16 41,986 40,659 -1,327 -3.16% x 1.03 num::bench_u32_from_str_radix_2 25,700 21,984 -3,716 -14.46% x 1.17 num::bench_u32_from_str_radix_36 40,881 36,783 -4,098 -10.02% x 1.11 num::bench_u64_from_str 23,685 23,756 71 0.30% x 1.00 num::bench_u64_from_str_radix_10 37,419 29,654 -7,765 -20.75% x 1.26 num::bench_u64_from_str_radix_16 41,441 32,673 -8,768 -21.16% x 1.27 num::bench_u64_from_str_radix_2 26,958 23,166 -3,792 -14.07% x 1.16 num::bench_u64_from_str_radix_36 43,619 34,687 -8,932 -20.48% x 1.26 num::bench_u8_from_str 24,187 24,219 32 0.13% x 1.00 num::bench_u8_from_str_radix_10 36,495 30,844 -5,651 -15.48% x 1.18 num::bench_u8_from_str_radix_16 35,309 31,433 -3,876 -10.98% x 1.12 num::bench_u8_from_str_radix_2 26,431 24,125 -2,306 -8.72% x 1.10 num::bench_u8_from_str_radix_36 36,213 31,624 -4,589 -12.67% x 1.15 ``` --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 30b7b45468412..87818b30084bb 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4438,7 +4438,7 @@ macro_rules! from_str_radix_int_impl { impl FromStr for $t { type Err = ParseIntError; fn from_str(src: &str) -> Result { - from_str_radix(src, 10) + <($t)>::from_str_radix(src, 10) } } )*}