Skip to content

Commit

Permalink
Auto merge of rust-lang#124774 - the8472:subnanosecond-benches, r=jhp…
Browse files Browse the repository at this point in the history
…ratt

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)
```
  • Loading branch information
bors committed May 10, 2024
2 parents f7b1501 + 2a7c42f commit e93f342
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 17 deletions.
23 changes: 13 additions & 10 deletions library/test/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, ',')
)
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions library/test/src/formatters/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
8 changes: 4 additions & 4 deletions src/bootstrap/src/utils/render_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
));
}

Expand Down Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/libtest-padding/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e93f342

Please sign in to comment.