Skip to content

Commit

Permalink
Merge pull request #1 from bluss/black-box-and-bench
Browse files Browse the repository at this point in the history
Black box and bench
  • Loading branch information
bluss authored Aug 21, 2016
2 parents c9df0af + d14efbb commit 675aebc
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ script:
travis-cargo build &&
travis-cargo test &&
travis-cargo test -- --release &&
travis-cargo bench -- --no-run &&
travis-cargo doc
travis-cargo doc &&
cargo bench
after_success:
# upload the documentation (GH_TOKEN from env)
- travis-cargo --only nightly doc-upload
Expand Down
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["bluss", "The Rust Project Developers"]
name = "bencher"
version = "0.1.0"
version = "0.1.1"

license = "MIT/Apache-2.0"

Expand All @@ -15,5 +15,10 @@ keywords = ["benchmark"]
[lib]
name = "bencher"
path = "lib.rs"
bench = false

[[bench]]
name = "example"
harness = false

[dependencies]
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ __ https://bluss.github.io/bencher/
Recent Changes
--------------

- 0.1.1

- Add a provisional implementation of ``black_box``. It's not as good as the
original version. (Since reproducibility is key, we will use the same
implementation on both stable and nightly.)
- Add example for how to set up this to run with ``cargo bench`` on stable.
This crate is itself an example of that, see ``Cargo.toml`` and ``benches/``

- 0.1.0

- Initial release
Expand Down
26 changes: 26 additions & 0 deletions benches/example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

// Also look in Cargo.toml how to use a benchmark setup with harness = false

#[macro_use]
extern crate bencher;

use bencher::Bencher;

fn a(bench: &mut Bencher) {
bench.iter(|| {
(0..1000).fold(0, |x, y| x + y)
})
}

fn b(bench: &mut Bencher) {
const N: usize = 1024;
bench.iter(|| {
vec![0u8; N]
});

bench.bytes = N as u64;
}

benchmark_group!(benches, a, b);
benchmark_main!(benches);

47 changes: 35 additions & 12 deletions lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@
//! macros that are used to describe benchmarker functions and
//! the benchmark runner.
//!
//! WARNING: There's no working black_box yet in this stable port of the benchmark runner.
//! This means that it easily happens that the optimizer removes too much of
//! the computation that you tried to benchmark.
//! WARNING: There's no proper black_box yet in this stable port of the benchmark runner,
//! only a workaround implementation. It may not work correctly and may have too
//! large overhead.
//!
//! One way to use this crate is to use it as dev-dependency and define
//! the benchmarks in an example that you compile and run using cargo. Don't forget
//! to use `--release`!.
//! One way to use this crate is to use it as dev-dependency and setup
//! cargo to compile a file in `benches/` that runs without the testing harness.
//!
//! In Cargo.toml:
//!
//! ```ignore
//! [[bench]]
//! name = "example"
//! harness = false
//! ```
//!
//! In benches/example.rs:
//!
//! ```
//! #[macro_use]
Expand All @@ -35,9 +44,12 @@
//! }
//!
//! fn b(bench: &mut Bencher) {
//! const N: usize = 1024;
//! bench.iter(|| {
//! String::new()
//! })
//! vec![0u8; N]
//! });
//!
//! bench.bytes = N as u64;
//! }
//!
//! benchmark_group!(benches, a, b);
Expand All @@ -46,6 +58,9 @@
//! # #[cfg(never)]
//! # fn main() { }
//! ```
//!
//! Use `cargo bench` as usual. A command line argument can be used to filter
//! which benchmarks to run.
pub use self::TestFn::*;
use self::TestResult::*;
Expand All @@ -61,7 +76,9 @@ use std::fs::File;
use std::io::prelude::*;
use std::io;
use std::iter::repeat;
use std::mem::forget;
use std::path::PathBuf;
use std::ptr;
use std::sync::mpsc::{channel, Sender};
use std::time::{Instant, Duration};

Expand Down Expand Up @@ -618,13 +635,19 @@ impl MetricMap {

// FIXME: We don't have black_box in stable rust

/// WARNING: We don't have a proper black box in stable Rust. This is
/// a workaround implementation, that may have a too big performance overhead,
/// depending on operation, or it may fail to properly avoid having code optimized out.
///
/// A function that is opaque to the optimizer, to allow benchmarks to
/// pretend to use outputs to assist in avoiding dead-code
/// elimination.
///
/// This function is a no-op, and does not even read from `dummy`.
fn black_box<T>(dummy: T) -> T {
dummy
pub fn black_box<T>(dummy: T) -> T {
unsafe {
let ret = ptr::read_volatile(&dummy as *const T);
forget(dummy);
ret
}
}


Expand Down
2 changes: 1 addition & 1 deletion macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ macro_rules! benchmark_main {
use $crate::run_tests_console;
let mut test_opts = TestOpts::default();
// check to see if we should filter:
for arg in ::std::env::args().skip(1) {
for arg in ::std::env::args().skip(1).filter(|arg| *arg != "--bench") {
test_opts.filter = Some(arg);
break;
}
Expand Down

0 comments on commit 675aebc

Please sign in to comment.