Skip to content

Commit e93f342

Browse files
committed
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) ```
2 parents f7b1501 + 2a7c42f commit e93f342

File tree

4 files changed

+20
-17
lines changed

4 files changed

+20
-17
lines changed

library/test/src/bench.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
6868
use std::fmt::Write;
6969
let mut output = String::new();
7070

71-
let median = bs.ns_iter_summ.median as usize;
72-
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
71+
let median = bs.ns_iter_summ.median;
72+
let deviation = bs.ns_iter_summ.max - bs.ns_iter_summ.min;
7373

7474
write!(
7575
output,
76-
"{:>11} ns/iter (+/- {})",
76+
"{:>14} ns/iter (+/- {})",
7777
fmt_thousands_sep(median, ','),
7878
fmt_thousands_sep(deviation, ',')
7979
)
@@ -85,24 +85,27 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
8585
}
8686

8787
// Format a number with thousands separators
88-
fn fmt_thousands_sep(mut n: usize, sep: char) -> String {
88+
fn fmt_thousands_sep(mut n: f64, sep: char) -> String {
8989
use std::fmt::Write;
9090
let mut output = String::new();
9191
let mut trailing = false;
9292
for &pow in &[9, 6, 3, 0] {
9393
let base = 10_usize.pow(pow);
94-
if pow == 0 || trailing || n / base != 0 {
95-
if !trailing {
96-
write!(output, "{}", n / base).unwrap();
97-
} else {
98-
write!(output, "{:03}", n / base).unwrap();
94+
if pow == 0 || trailing || n / base as f64 >= 1.0 {
95+
match (pow, trailing) {
96+
// modern CPUs can execute multiple instructions per nanosecond
97+
// e.g. benching an ADD takes about 0.25ns.
98+
(0, true) => write!(output, "{:06.2}", n / base as f64).unwrap(),
99+
(0, false) => write!(output, "{:.2}", n / base as f64).unwrap(),
100+
(_, true) => write!(output, "{:03}", n as usize / base).unwrap(),
101+
_ => write!(output, "{}", n as usize / base).unwrap()
99102
}
100103
if pow != 0 {
101104
output.push(sep);
102105
}
103106
trailing = true;
104107
}
105-
n %= base;
108+
n %= base as f64;
106109
}
107110

108111
output

library/test/src/formatters/json.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,8 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
167167
),
168168

169169
TestResult::TrBench(ref bs) => {
170-
let median = bs.ns_iter_summ.median as usize;
171-
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
170+
let median = bs.ns_iter_summ.median;
171+
let deviation = bs.ns_iter_summ.max - bs.ns_iter_summ.min;
172172

173173
let mbps = if bs.mb_s == 0 {
174174
String::new()

src/bootstrap/src/utils/render_tests.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ impl<'a> Renderer<'a> {
215215
for bench in &self.benches {
216216
rows.push((
217217
&bench.name,
218-
format!("{:.2?}/iter", Duration::from_nanos(bench.median)),
219-
format!("+/- {:.2?}", Duration::from_nanos(bench.deviation)),
218+
format!("{:.2?}/iter", bench.median),
219+
format!("+/- {:.2?}", bench.deviation),
220220
));
221221
}
222222

@@ -394,8 +394,8 @@ enum TestMessage {
394394
#[derive(serde_derive::Deserialize)]
395395
struct BenchOutcome {
396396
name: String,
397-
median: u64,
398-
deviation: u64,
397+
median: f64,
398+
deviation: f64,
399399
}
400400

401401
#[derive(serde_derive::Deserialize)]

tests/run-make/libtest-padding/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# needs-unwind because #[bench] and -Cpanic=abort requires -Zpanic-abort-tests
33
include ../tools.mk
44

5-
NORMALIZE=sed 's%[0-9,]\{1,\} ns/iter (+/- [0-9,]\{1,\})%?? ns/iter (+/- ??)%' | sed 's%finished in [0-9\.]\{1,\}%finished in ??%'
5+
NORMALIZE=sed 's%[0-9,\.]\{1,\} ns/iter (+/- [0-9,\.]\{1,\})%?? ns/iter (+/- ??)%' | sed 's%finished in [0-9\.]\{1,\}%finished in ??%'
66

77
all:
88
$(RUSTC) --test tests.rs

0 commit comments

Comments
 (0)