diff options
| author | bors <bors@rust-lang.org> | 2024-05-10 08:59:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-05-10 08:59:08 +0000 |
| commit | e93f34210120d1fc6a0195d527eee828a36e57b1 (patch) | |
| tree | 276e29caddbc4b3116b4843f085d90315f9abedf | |
| parent | f7b1501ce7e63a53b36f9d6d01b939eef6602d42 (diff) | |
| parent | 2a7c42f93c2e3e3c07a8cae6453e4c7626e83b51 (diff) | |
| download | rust-e93f34210120d1fc6a0195d527eee828a36e57b1.tar.gz rust-e93f34210120d1fc6a0195d527eee828a36e57b1.zip | |
Auto merge of #124774 - the8472:subnanosecond-benches, r=jhpratt
Display walltime benchmarks with subnanosecond precision With modern CPUs running at more than one cycle per nanosecond the current precision is insufficient to resolve differences worth several cycles per iteration. Granted, walltime benchmarks often are noisy but occasionally, especially when no allocations are involved, the difference really is just a few cycles. example results when benchmarking 1-4 serialized ADD instructions and an empty bench body ``` running 4 tests test add ... bench: 0.24 ns/iter (+/- 0.00) test add2 ... bench: 0.48 ns/iter (+/- 0.01) test add3 ... bench: 0.72 ns/iter (+/- 0.01) test add4 ... bench: 0.96 ns/iter (+/- 0.01) test empty ... bench: 0.24 ns/iter (+/- 0.00) ```
| -rw-r--r-- | library/test/src/bench.rs | 23 | ||||
| -rw-r--r-- | library/test/src/formatters/json.rs | 4 | ||||
| -rw-r--r-- | src/bootstrap/src/utils/render_tests.rs | 8 | ||||
| -rw-r--r-- | tests/run-make/libtest-padding/Makefile | 2 |
4 files changed, 20 insertions, 17 deletions
diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs index 23925e6ea72..9a5dc351f6d 100644 --- a/library/test/src/bench.rs +++ b/library/test/src/bench.rs @@ -68,12 +68,12 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String { use std::fmt::Write; let mut output = String::new(); - let median = bs.ns_iter_summ.median as usize; - let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize; + let median = bs.ns_iter_summ.median; + let deviation = bs.ns_iter_summ.max - bs.ns_iter_summ.min; write!( output, - "{:>11} ns/iter (+/- {})", + "{:>14} ns/iter (+/- {})", fmt_thousands_sep(median, ','), fmt_thousands_sep(deviation, ',') ) @@ -85,24 +85,27 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String { } // Format a number with thousands separators -fn fmt_thousands_sep(mut n: usize, sep: char) -> String { +fn fmt_thousands_sep(mut n: f64, sep: char) -> String { use std::fmt::Write; let mut output = String::new(); let mut trailing = false; for &pow in &[9, 6, 3, 0] { let base = 10_usize.pow(pow); - if pow == 0 || trailing || n / base != 0 { - if !trailing { - write!(output, "{}", n / base).unwrap(); - } else { - write!(output, "{:03}", n / base).unwrap(); + if pow == 0 || trailing || n / base as f64 >= 1.0 { + match (pow, trailing) { + // modern CPUs can execute multiple instructions per nanosecond + // e.g. benching an ADD takes about 0.25ns. + (0, true) => write!(output, "{:06.2}", n / base as f64).unwrap(), + (0, false) => write!(output, "{:.2}", n / base as f64).unwrap(), + (_, true) => write!(output, "{:03}", n as usize / base).unwrap(), + _ => write!(output, "{}", n as usize / base).unwrap() } if pow != 0 { output.push(sep); } trailing = true; } - n %= base; + n %= base as f64; } output diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index 47c4e7757e4..6245aae17c4 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -167,8 +167,8 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { ), TestResult::TrBench(ref bs) => { - let median = bs.ns_iter_summ.median as usize; - let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize; + let median = bs.ns_iter_summ.median; + let deviation = bs.ns_iter_summ.max - bs.ns_iter_summ.min; let mbps = if bs.mb_s == 0 { String::new() diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 462b76d03bd..5c9918bce32 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -215,8 +215,8 @@ impl<'a> Renderer<'a> { for bench in &self.benches { rows.push(( &bench.name, - format!("{:.2?}/iter", Duration::from_nanos(bench.median)), - format!("+/- {:.2?}", Duration::from_nanos(bench.deviation)), + format!("{:.2?}/iter", bench.median), + format!("+/- {:.2?}", bench.deviation), )); } @@ -394,8 +394,8 @@ enum TestMessage { #[derive(serde_derive::Deserialize)] struct BenchOutcome { name: String, - median: u64, - deviation: u64, + median: f64, + deviation: f64, } #[derive(serde_derive::Deserialize)] diff --git a/tests/run-make/libtest-padding/Makefile b/tests/run-make/libtest-padding/Makefile index 42bc1192925..c8e2fc01f67 100644 --- a/tests/run-make/libtest-padding/Makefile +++ b/tests/run-make/libtest-padding/Makefile @@ -2,7 +2,7 @@ # needs-unwind because #[bench] and -Cpanic=abort requires -Zpanic-abort-tests include ../tools.mk -NORMALIZE=sed 's%[0-9,]\{1,\} ns/iter (+/- [0-9,]\{1,\})%?? ns/iter (+/- ??)%' | sed 's%finished in [0-9\.]\{1,\}%finished in ??%' +NORMALIZE=sed 's%[0-9,\.]\{1,\} ns/iter (+/- [0-9,\.]\{1,\})%?? ns/iter (+/- ??)%' | sed 's%finished in [0-9\.]\{1,\}%finished in ??%' all: $(RUSTC) --test tests.rs |
