Skip to content

Move test::Bencher to a new (unstable) std::bench module #66290

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

Closed
wants to merge 2 commits into from

Conversation

SimonSapin
Copy link
Contributor

This is a first step toward stabilizing it and the #[bench] attribute: #66287

To avoid also moving much of the test crate Bencher is now only responsible for runnning user code and measuring the time it takes, not anymore for doing statistical analysis. This separation is based on &mut dyn FnMut callbacks.

This introduces dynamic dispatch, which in general could affect performance characteristics of a program. However I expect benchmarking results not to be affected here since the {Instant::new; user code; Instant::elapsed} sequence is kept monomorphized and not crossing a dynamic dispatch boundary.

This also adds a lifetime parameter to the Bencher struct, which is is technically a breaking change to an unstable type. I expect the impact to be low on existing users: only those with #[deny(warnings)] or #[deny(elided_lifetimes_in_paths)] would need to change their code. (See second commit.) This lint is allow by default.

This is a first step toward stabilizing it and the `#[bench]` attribute:
rust-lang#66287

To avoid also moving much of the `test` crate `Bencher` is now only
responsible for runnning user code and measuring the time it takes,
not anymore for doing statistical analysis.
This separation is based on `&mut dyn FnMut` callbacks.

This introduces dynamic dispatch, which in general could affect performance
characteristics of a program. However I expect benchmarking results not to be
affected here since the {`Instant::new`; user code; `Instant::elapsed`}
sequence is kept monomorphized and not crossing a dynamic dispatch boundary.

This also adds a lifetime parameter to the `Bencher` struct,
which is is technically a breaking change to an unstable type.
I expect the impact to be low on existing users: only those with
`#[deny(warnings)]` or `#[deny(elided_lifetimes_in_paths)]`
would need to change their code. (See next commit.)
This lint is `allow` by default.
…ith `-D warnings`

This fixes errors such as:

```rust
error: hidden lifetime parameters in types are deprecated
  --> src/libserialize/hex/tests.rs:56:29
   |
56 | pub fn bench_to_hex(b: &mut Bencher) {
   |                             ^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
   |
   = note: `-D elided-lifetimes-in-paths` implied by `-D warnings`
```

Note however that the relevant lint is `allow` by default,
so most crates are not similarly affected.
@rust-highfive
Copy link
Contributor

r? @rkruppe

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 11, 2019
@@ -454,6 +454,7 @@ pub mod f64;
pub mod thread;
pub mod ascii;
pub mod backtrace;
pub mod bench;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't the module also have a stability annotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes? It’s near the top of libstd/bench.rs, like for most other modules under std::

Copy link
Contributor

Choose a reason for hiding this comment

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

I saw that, but I guess it isn't necessary on the mod item itself?

Copy link
Contributor Author

@SimonSapin SimonSapin Nov 11, 2019

Choose a reason for hiding this comment

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

This (inner) attribute is already on the mod item. If we switch to inline module syntax, this PR is equivalent to:

pub mod bench {
    #![unstable()]
    // …
}

Which is equivalent to an outer attribute:

#[unstable()]
pub mod bench {
    // …
}

@elichai
Copy link
Contributor

elichai commented Nov 11, 2019

May I ask why dynamic dispatch and not generic?

@SimonSapin
Copy link
Contributor Author

Dynamic dispatch avoids forcing a type parameter on all functions with the #[bench] attribute. And passing impl FnMut to another impl FnMut would require the outer one to be a higher-kinded type, which don’t exist in the language (at least today).

@JohnCSimon
Copy link
Member

Ping from triage:
@rkruppe Can you please review this PR? thank you
cc: @SimonSapin @elichai @Centril

@SimonSapin
Copy link
Contributor Author

This PR has served its initial purpose of demonstrating feasibility. I’ll close it now to avoid keeping it open for a long time on triage’s radar. We can re-open it if and when we decide in #66287 or in an RFC that this the approach we want.

@SimonSapin SimonSapin closed this Nov 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants