Skip to content

Address testing guide nits #19888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 6, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/doc/guide-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ Advice on writing benchmarks:
* Make the code in the `iter` loop do something simple, to assist in pinpointing
performance improvements (or regressions)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This benchmark is still incorrect: the text implies that this new benchmark is then fixed (i.e. accurately benchmarking the time it takes to xor 1000 uints), but it's not. It looks like we may need a new benchmark, or stronger black-boxing:

let mut n = 1000;
// `n` is unchanged, butthe optimiser is forced to assume that `n` may be mutated
test::black_box(&mut n);

b.iter(|| {
    test::black_box(range(0u, n).fold(...));
})

(or the version that does the range.fold without a semicolon.)

I haven't tested that, but one should see numbers on the order of the 375 ns/iter that it was before (the exact values isn't too important and varies based on the specific computer, but it should certainly be hundreds of nanoseconds, not ones).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to finish this PR up, did you ever come up with a good replacement?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, whoops, forgot to write it down:

    b.iter(|| {
        let mut n = 1000_u32;
        test::black_box(&mut n); // pretend to modify `n`
        range(0, n).fold(0, |a, b| a ^ b)
    })

## Gotcha: optimizations

There's another tricky part to writing benchmarks: benchmarks compiled with
optimizations activated can be dramatically changed by the optimizer so that
the benchmark is no longer benchmarking what one expects. For example, the
Expand Down Expand Up @@ -554,8 +556,12 @@ extern crate test;
# fn main() {
# struct X; impl X { fn iter<T>(&self, _: || -> T) {} } let b = X;
b.iter(|| {
test::black_box(range(0u, 1000).fold(0, |old, new| old ^ new));
});
let mut n = 1000_u32;

test::black_box(&mut n); // pretend to modify `n`

range(0, n).fold(0, |a, b| a ^ b)
})
# }
```

Expand All @@ -571,3 +577,6 @@ test bench_xor_1000_ints ... bench: 1 ns/iter (+/- 0)

test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
```

However, the optimizer can still modify a testcase in an undesirable manner
even when using either of the above.