From a800e3e3144e773326685c0250003cf98a9994f9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 5 Jan 2015 16:13:56 -0800 Subject: [PATCH] Finalize story for libtest One of the last remaining crates to have a stabilization story in the standard distribution is the libtest library. This library currently provides the backing infrastructure and test harness used when rustc generates a test execuable via the `--test` command line flag. It's well known that libtest is not the end-all-be-all of testing frameworks. It is intentionally minimal and is currently quite conservative in its scope of what it tries to accomplish as well as what it implements. A testament to this is the fact that one very rarely writes `extern crate test`, and it almost means that the stabilization story need not be considered for the crate at all! The benchmarking feature of the compiler, however, is quite useful and is one of the sole reasons for using `extern crate test`. When benchmarking, there are a few primary interfaces to the libtest library that are used: * `test::Bencher` - the type for a benchmarking harness. * `test::Bencher::iter` - a member function used to run a benchmark. * `test::black_box` - a useful function to hinder optimizations and prevent a value from being optimized away. These three pieces of information are the primary targets for the stabilization in this commit. The rest of the testing infrastructure, while still quite useful to some projects, is not in scope for stabilization at 1.0 and will remain `#[experimental]` for now. The benchmarking pieces have been moved to a new `rustc_bench` crate which will be part of the standard distribution. In order to write a benchmark one will need to import the crate via `extern crate rustc_bench` and otherwise all usage remains the same. The purpose of this crate is to provide a clear area for these benchmarking utilities as well as provide a clear name that it is *only* intended for use via the compiler `#[bench]` attribute. The current interface is quite minimal with only what's necessary as `#[stable]`. It is most certainly a desire for the compiler to support other testing frameworks other than the standard libtest. This form of infrastructure (be it a plugin or a separate interface) is out of scope for 1.0, however, and this commit does not attempt to resolve it. Due to the removal of benchmarking items from libtest, this is a breaking change. To update, rewrite imports of `extern crate test` to `extern crate rustc_bench` and then rewrite all `use` statements as well. The public interface of the `Bencher` struct has not changed. [breaking-change] --- mk/crates.mk | 6 +- src/doc/guide-testing.md | 23 ++-- src/liballoc/heap.rs | 4 +- src/libarena/lib.rs | 4 +- src/libcollections/bench.rs | 2 +- src/libcollections/bit.rs | 8 +- src/libcollections/btree/map.rs | 2 +- src/libcollections/dlist.rs | 21 ++-- src/libcollections/lib.rs | 2 +- src/libcollections/ring_buf.rs | 31 +++-- src/libcollections/slice.rs | 2 +- src/libcollections/str.rs | 7 +- src/libcollections/string.rs | 2 +- src/libcollections/vec.rs | 2 +- src/libcollections/vec_map.rs | 2 +- src/libcore/hash/sip.rs | 2 +- src/libcoretest/any.rs | 7 +- src/libcoretest/fmt/num.rs | 4 +- src/libcoretest/hash/sip.rs | 2 +- src/libcoretest/iter.rs | 2 +- src/libcoretest/lib.rs | 2 +- src/libcoretest/mem.rs | 2 +- src/libcoretest/ops.rs | 2 +- src/liblibc/lib.rs | 1 - src/librand/distributions/exponential.rs | 4 +- src/librand/distributions/gamma.rs | 3 +- src/librand/distributions/normal.rs | 3 +- src/librand/lib.rs | 2 + src/librbml/io.rs | 3 +- src/librbml/lib.rs | 4 +- src/libregex/lib.rs | 2 +- src/libregex/test/bench.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_back/sha2.rs | 4 +- src/librustc_bench/lib.rs | 86 ++++++++++++++ src/libserialize/base64.rs | 4 +- src/libserialize/hex.rs | 4 +- src/libserialize/json.rs | 4 +- src/libserialize/lib.rs | 2 +- src/libstd/collections/hash/bench.rs | 3 +- src/libstd/io/buffered.rs | 3 +- src/libstd/io/extensions.rs | 4 +- src/libstd/io/mem.rs | 9 +- src/libstd/lib.rs | 5 +- src/libstd/num/mod.rs | 3 +- src/libstd/num/strconv.rs | 8 +- src/libstd/path/posix.rs | 3 +- src/libstd/rand/mod.rs | 3 +- src/libtest/lib.rs | 118 +++++++------------- src/libtest/stats.rs | 2 +- src/test/compile-fail/view-items-at-top.rs | 4 +- src/test/run-pass/attr-before-view-item.rs | 2 +- src/test/run-pass/attr-before-view-item2.rs | 2 +- 53 files changed, 239 insertions(+), 201 deletions(-) create mode 100644 src/librustc_bench/lib.rs diff --git a/mk/crates.mk b/mk/crates.mk index cea92e19a2682..edff8f975d054 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -52,7 +52,7 @@ TARGET_CRATES := libc std flate arena term \ serialize getopts collections test rand \ log regex graphviz core rbml alloc \ - unicode + unicode rustc_bench RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \ rustc_trans rustc_back rustc_llvm HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros @@ -90,11 +90,13 @@ DEPS_term := std log DEPS_getopts := std DEPS_collections := core alloc unicode DEPS_num := std -DEPS_test := std getopts serialize rbml term regex native:rust_test_helpers +DEPS_test := std getopts serialize rbml term regex native:rust_test_helpers \ + rustc_bench DEPS_rand := core DEPS_log := std regex DEPS_regex := std DEPS_fmt_macros = std +DEPS_rustc_bench := std TOOL_DEPS_compiletest := test getopts TOOL_DEPS_rustdoc := rustdoc diff --git a/src/doc/guide-testing.md b/src/doc/guide-testing.md index 4c3d93bdfbe5f..ac55adbba6246 100644 --- a/src/doc/guide-testing.md +++ b/src/doc/guide-testing.md @@ -1,7 +1,7 @@ % The Rust Testing Guide > Program testing can be a very effective way to show the presence of bugs, but -> it is hopelessly inadequate for showing their absence. +> it is hopelessly inadequate for showing their absence. > > Edsger W. Dijkstra, "The Humble Programmer" (1972) @@ -310,7 +310,7 @@ extern crate adder; #[test] fn it_works() { assert_eq(4, adder::add_two(2)); -} +} ``` This looks similar to our previous tests, but slightly different. We now have @@ -442,7 +442,7 @@ code. Let's make our `src/lib.rs` look like this (comments elided): ```{rust,ignore} #![feature(globs)] -extern crate test; +extern crate rustc_bench; pub fn add_two(a: i32) -> i32 { a + 2 @@ -451,7 +451,7 @@ pub fn add_two(a: i32) -> i32 { #[cfg(test)] mod tests { use super::*; - use test::Bencher; + use rustc_bench::Bencher; #[test] fn it_works() { @@ -512,8 +512,8 @@ compiler might recognize that some calculation has no external effects and remove it entirely. ```{rust,ignore} -extern crate test; -use test::Bencher; +extern crate rustc_bench; +use rustc_bench::Bencher; #[bench] fn bench_xor_1000_ints(b: &mut Bencher) { @@ -547,20 +547,19 @@ b.iter(|| { }); ``` -Or, the other option is to call the generic `test::black_box` function, which -is an opaque "black box" to the optimizer and so forces it to consider any -argument as used. +Or, the other option is to call the generic `rustc_bench::black_box` function, +which is an opaque "black box" to the optimizer and so forces it to consider +any argument as used. ```rust -extern crate test; - +extern crate rustc_bench; # fn main() { # struct X; # impl X { fn iter(&self, _: F) where F: FnMut() -> T {} } let b = X; b.iter(|| { let mut n = 1000_u32; - test::black_box(&mut n); // pretend to modify `n` + rustc_bench::black_box(&mut n); // pretend to modify `n` range(0, n).fold(0, |a, b| a ^ b) }) diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index c57435cdc8c0c..4e70e66d8d298 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -370,8 +370,8 @@ mod imp { #[cfg(test)] mod test { - extern crate test; - use self::test::Bencher; + extern crate rustc_bench; + use self::rustc_bench::Bencher; use core::ptr::PtrExt; use heap; diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 423c16bfee8e8..95d793df2aaa3 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -507,8 +507,8 @@ impl Drop for TypedArena { #[cfg(test)] mod tests { - extern crate test; - use self::test::Bencher; + extern crate rustc_bench; + use self::rustc_bench::Bencher; use super::{Arena, TypedArena}; #[allow(dead_code)] diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs index cd4f8d203dfe9..8ab644660803d 100644 --- a/src/libcollections/bench.rs +++ b/src/libcollections/bench.rs @@ -11,7 +11,7 @@ use prelude::*; use std::rand; use std::rand::Rng; -use test::{Bencher, black_box}; +use rustc_bench::{Bencher, black_box}; pub fn insert_rand_n(n: uint, map: &mut M, diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 2154d06377a19..8a1373c5ddf55 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -2507,7 +2507,7 @@ mod bitv_bench { use std::rand; use std::rand::Rng; use std::u32; - use test::{Bencher, black_box}; + use rustc_bench::{Bencher, black_box}; use super::Bitv; @@ -2526,7 +2526,7 @@ mod bitv_bench { for _ in range(0u, 100) { bitv |= 1 << ((r.next_u32() as uint) % u32::BITS); } - black_box(&bitv) + black_box(&bitv); }); } @@ -2538,7 +2538,7 @@ mod bitv_bench { for _ in range(0u, 100) { bitv.set((r.next_u32() as uint) % BENCH_BITS, true); } - black_box(&bitv) + black_box(&bitv); }); } @@ -3002,7 +3002,7 @@ mod bitv_set_bench { use std::rand; use std::rand::Rng; use std::u32; - use test::{Bencher, black_box}; + use rustc_bench::{Bencher, black_box}; use super::{Bitv, BitvSet}; diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 4e44779810b29..6bf2c70539b19 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -1614,7 +1614,7 @@ mod test { mod bench { use prelude::*; use std::rand::{weak_rng, Rng}; - use test::{Bencher, black_box}; + use rustc_bench::{Bencher, black_box}; use super::BTreeMap; use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 63ea9f7cb4322..0e13804820a7d 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -690,8 +690,7 @@ mod tests { use std::rand; use std::hash; use std::thread::Thread; - use test::Bencher; - use test; + use rustc_bench::Bencher; use super::{DList, Node}; @@ -1101,7 +1100,7 @@ mod tests { } #[bench] - fn bench_collect_into(b: &mut test::Bencher) { + fn bench_collect_into(b: &mut Bencher) { let v = &[0i; 64]; b.iter(|| { let _: DList = v.iter().map(|x| *x).collect(); @@ -1109,7 +1108,7 @@ mod tests { } #[bench] - fn bench_push_front(b: &mut test::Bencher) { + fn bench_push_front(b: &mut Bencher) { let mut m: DList = DList::new(); b.iter(|| { m.push_front(0); @@ -1117,7 +1116,7 @@ mod tests { } #[bench] - fn bench_push_back(b: &mut test::Bencher) { + fn bench_push_back(b: &mut Bencher) { let mut m: DList = DList::new(); b.iter(|| { m.push_back(0); @@ -1125,7 +1124,7 @@ mod tests { } #[bench] - fn bench_push_back_pop_back(b: &mut test::Bencher) { + fn bench_push_back_pop_back(b: &mut Bencher) { let mut m: DList = DList::new(); b.iter(|| { m.push_back(0); @@ -1134,7 +1133,7 @@ mod tests { } #[bench] - fn bench_push_front_pop_front(b: &mut test::Bencher) { + fn bench_push_front_pop_front(b: &mut Bencher) { let mut m: DList = DList::new(); b.iter(|| { m.push_front(0); @@ -1143,7 +1142,7 @@ mod tests { } #[bench] - fn bench_iter(b: &mut test::Bencher) { + fn bench_iter(b: &mut Bencher) { let v = &[0i; 128]; let m: DList = v.iter().map(|&x|x).collect(); b.iter(|| { @@ -1151,7 +1150,7 @@ mod tests { }) } #[bench] - fn bench_iter_mut(b: &mut test::Bencher) { + fn bench_iter_mut(b: &mut Bencher) { let v = &[0i; 128]; let mut m: DList = v.iter().map(|&x|x).collect(); b.iter(|| { @@ -1159,7 +1158,7 @@ mod tests { }) } #[bench] - fn bench_iter_rev(b: &mut test::Bencher) { + fn bench_iter_rev(b: &mut Bencher) { let v = &[0i; 128]; let m: DList = v.iter().map(|&x|x).collect(); b.iter(|| { @@ -1167,7 +1166,7 @@ mod tests { }) } #[bench] - fn bench_iter_mut_rev(b: &mut test::Bencher) { + fn bench_iter_mut_rev(b: &mut Bencher) { let v = &[0i; 128]; let mut m: DList = v.iter().map(|&x|x).collect(); b.iter(|| { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 6eab36d8844df..6d40dbf7c7551 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -33,7 +33,7 @@ extern crate core; extern crate unicode; extern crate alloc; -#[cfg(test)] extern crate test; +#[cfg(test)] extern crate rustc_bench; #[cfg(test)] #[macro_use] extern crate std; #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 42c17136a0882..5898da5932d7c 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -1632,8 +1632,7 @@ mod tests { use core::iter; use std::fmt::Show; use std::hash; - use test::Bencher; - use test; + use rustc_bench::{Bencher, black_box}; use super::RingBuf; @@ -1750,15 +1749,15 @@ mod tests { } #[bench] - fn bench_new(b: &mut test::Bencher) { + fn bench_new(b: &mut Bencher) { b.iter(|| { let ring: RingBuf = RingBuf::new(); - test::black_box(ring); + black_box(ring); }) } #[bench] - fn bench_push_back_100(b: &mut test::Bencher) { + fn bench_push_back_100(b: &mut Bencher) { let mut deq = RingBuf::with_capacity(101); b.iter(|| { for i in range(0i, 100) { @@ -1770,7 +1769,7 @@ mod tests { } #[bench] - fn bench_push_front_100(b: &mut test::Bencher) { + fn bench_push_front_100(b: &mut Bencher) { let mut deq = RingBuf::with_capacity(101); b.iter(|| { for i in range(0i, 100) { @@ -1782,44 +1781,44 @@ mod tests { } #[bench] - fn bench_pop_back_100(b: &mut test::Bencher) { + fn bench_pop_back_100(b: &mut Bencher) { let mut deq: RingBuf = RingBuf::with_capacity(101); b.iter(|| { deq.head = 100; deq.tail = 0; while !deq.is_empty() { - test::black_box(deq.pop_back()); + black_box(deq.pop_back()); } }) } #[bench] - fn bench_pop_front_100(b: &mut test::Bencher) { + fn bench_pop_front_100(b: &mut Bencher) { let mut deq: RingBuf = RingBuf::with_capacity(101); b.iter(|| { deq.head = 100; deq.tail = 0; while !deq.is_empty() { - test::black_box(deq.pop_front()); + black_box(deq.pop_front()); } }) } #[bench] - fn bench_grow_1025(b: &mut test::Bencher) { + fn bench_grow_1025(b: &mut Bencher) { b.iter(|| { let mut deq = RingBuf::new(); for i in range(0i, 1025) { deq.push_front(i); } - test::black_box(deq); + black_box(deq); }) } #[bench] - fn bench_iter_1000(b: &mut test::Bencher) { + fn bench_iter_1000(b: &mut Bencher) { let ring: RingBuf = range(0i, 1000).collect(); b.iter(|| { @@ -1827,12 +1826,12 @@ mod tests { for &i in ring.iter() { sum += i; } - test::black_box(sum); + black_box(sum); }) } #[bench] - fn bench_mut_iter_1000(b: &mut test::Bencher) { + fn bench_mut_iter_1000(b: &mut Bencher) { let mut ring: RingBuf = range(0i, 1000).collect(); b.iter(|| { @@ -1840,7 +1839,7 @@ mod tests { for i in ring.iter_mut() { sum += *i; } - test::black_box(sum); + black_box(sum); }) } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 582887ac38a53..6dbf628d07d42 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -2730,7 +2730,7 @@ mod bench { use core::ptr; use core::iter::repeat; use std::rand::{weak_rng, Rng}; - use test::{Bencher, black_box}; + use rustc_bench::{Bencher, black_box}; #[bench] fn iterator(b: &mut Bencher) { diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 09d140067f451..980ab61a3bd1e 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -2826,8 +2826,7 @@ mod tests { mod bench { use super::*; use prelude::{SliceExt, IteratorExt, SliceConcatExt}; - use test::Bencher; - use test::black_box; + use rustc_bench::{Bencher, black_box}; #[bench] fn char_iterator(b: &mut Bencher) { @@ -2841,7 +2840,7 @@ mod bench { let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; b.iter(|| { - for ch in s.chars() { black_box(ch) } + for ch in s.chars() { black_box(ch); } }); } @@ -2869,7 +2868,7 @@ mod bench { let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; b.iter(|| { - for ch in s.chars().rev() { black_box(ch) } + for ch in s.chars().rev() { black_box(ch); } }); } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 59418f50e3c7d..0afeeba9b7382 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -976,7 +976,7 @@ impl fmt::Writer for String { #[cfg(test)] mod tests { use prelude::*; - use test::Bencher; + use rustc_bench::Bencher; use str::Utf8Error; use core::iter::repeat; diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 5fc3fafac9e22..6c5cd7c4d8ff8 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1816,7 +1816,7 @@ mod tests { use core::mem::size_of; use core::iter::repeat; use core::ops::FullRange; - use test::Bencher; + use rustc_bench::Bencher; use super::as_vec; struct DropCounter<'a> { diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 4399a6fec2274..25ca432f41712 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -1058,7 +1058,7 @@ mod test_map { #[cfg(test)] mod bench { - use test::Bencher; + use rustc_bench::Bencher; use super::VecMap; use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index c4d45e9c2c804..825eefb711ba6 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -271,7 +271,7 @@ pub fn hash_with_keys>(k0: u64, k1: u64, value: &T) - #[cfg(test)] mod tests { - use test::Bencher; + use rustc_bench::Bencher; use prelude::*; use std::fmt; diff --git a/src/libcoretest/any.rs b/src/libcoretest/any.rs index c0be3a287940a..3cbff612b9759 100644 --- a/src/libcoretest/any.rs +++ b/src/libcoretest/any.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. use core::any::*; -use test::Bencher; -use test; +use rustc_bench::{Bencher, black_box}; #[derive(PartialEq, Show)] struct Test; @@ -125,7 +124,7 @@ fn bench_downcast_ref(b: &mut Bencher) { b.iter(|| { let mut x = 0i; let mut y = &mut x as &mut Any; - test::black_box(&mut y); - test::black_box(y.downcast_ref::() == Some(&0)); + black_box(&mut y); + black_box(y.downcast_ref::() == Some(&0)); }); } diff --git a/src/libcoretest/fmt/num.rs b/src/libcoretest/fmt/num.rs index c259e4cbb686d..e9709c8129556 100644 --- a/src/libcoretest/fmt/num.rs +++ b/src/libcoretest/fmt/num.rs @@ -167,7 +167,7 @@ fn test_radix_base_too_large() { } mod uint { - use test::Bencher; + use rustc_bench::Bencher; use core::fmt::radix; use std::rand::{weak_rng, Rng}; @@ -209,7 +209,7 @@ mod uint { } mod int { - use test::Bencher; + use rustc_bench::Bencher; use core::fmt::radix; use std::rand::{weak_rng, Rng}; diff --git a/src/libcoretest/hash/sip.rs b/src/libcoretest/hash/sip.rs index 431f7e748f6db..4931d73b5f2a8 100644 --- a/src/libcoretest/hash/sip.rs +++ b/src/libcoretest/hash/sip.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -use test::Bencher; +use rustc_bench::Bencher; use std::prelude::*; use std::fmt; diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 61266a9264944..5c03f2c173766 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -15,7 +15,7 @@ use core::num::SignedInt; use core::uint; use core::cmp; -use test::Bencher; +use rustc_bench::Bencher; #[test] fn test_lt() { diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 50ae59e70dc93..2b771eba0fc22 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -11,7 +11,7 @@ #![feature(unboxed_closures)] extern crate core; -extern crate test; +extern crate rustc_bench; extern crate libc; extern crate unicode; diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 96b50e8bccbad..37397778fa2df 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. use core::mem::*; -use test::Bencher; +use rustc_bench::Bencher; #[test] fn size_of_basic() { diff --git a/src/libcoretest/ops.rs b/src/libcoretest/ops.rs index 430188c7e4322..d9c7166537888 100644 --- a/src/libcoretest/ops.rs +++ b/src/libcoretest/ops.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use test::Bencher; +use rustc_bench::Bencher; use core::ops::{Range, FullRange, RangeFrom, RangeTo}; // Overhead of dtors diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index e48272b4e09da..fdae1949076d0 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -80,7 +80,6 @@ extern crate core; #[cfg(test)] extern crate std; -#[cfg(test)] extern crate test; pub use self::Nullable::*; diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs index 580f8897885f6..48b907d0bd49a 100644 --- a/src/librand/distributions/exponential.rs +++ b/src/librand/distributions/exponential.rs @@ -122,11 +122,11 @@ mod test { #[cfg(test)] mod bench { - extern crate test; + extern crate rustc_bench; use std::prelude::v1::*; - use self::test::Bencher; + use self::rustc_bench::Bencher; use std::mem::size_of; use super::Exp; use distributions::Sample; diff --git a/src/librand/distributions/gamma.rs b/src/librand/distributions/gamma.rs index 378029d1f9b37..3eb1a4b909141 100644 --- a/src/librand/distributions/gamma.rs +++ b/src/librand/distributions/gamma.rs @@ -384,9 +384,8 @@ mod test { #[cfg(test)] mod bench { - extern crate test; use std::prelude::v1::*; - use self::test::Bencher; + use rustc_bench::Bencher; use std::mem::size_of; use distributions::IndependentSample; use super::Gamma; diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs index 2e1a433eb075e..2f1df2dbe6489 100644 --- a/src/librand/distributions/normal.rs +++ b/src/librand/distributions/normal.rs @@ -199,9 +199,8 @@ mod tests { #[cfg(test)] mod bench { - extern crate test; use std::prelude::v1::*; - use self::test::Bencher; + use rustc_bench::Bencher; use std::mem::size_of; use distributions::{Sample}; use super::Normal; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index ad2a4dbec4e92..c4aaf2382441f 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -32,6 +32,8 @@ extern crate core; #[cfg(test)] #[macro_use] extern crate std; #[cfg(test)] #[macro_use] extern crate log; +#[cfg(test)] extern crate rustc_bench; + use core::prelude::*; pub use isaac::{IsaacRng, Isaac64Rng}; diff --git a/src/librbml/io.rs b/src/librbml/io.rs index 5ebec32d73384..cb8809dbfc1c2 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -130,11 +130,10 @@ impl Seek for SeekableMemWriter { #[cfg(test)] mod tests { - extern crate test; use super::SeekableMemWriter; use std::io; use std::iter::repeat; - use test::Bencher; + use rustc_bench::Bencher; #[test] fn test_seekable_mem_writer() { diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index a66d1dd08c1eb..68586460c3ba0 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -29,7 +29,7 @@ extern crate serialize; #[macro_use] extern crate log; -#[cfg(test)] extern crate test; +#[cfg(test)] extern crate rustc_bench; pub use self::EbmlEncoderTag::*; pub use self::Error::*; @@ -1161,7 +1161,7 @@ mod tests { #[cfg(test)] mod bench { #![allow(non_snake_case)] - use test::Bencher; + use rustc_bench::Bencher; use super::reader; #[bench] diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs index c039abc9aff2a..d49436c3fc6cf 100644 --- a/src/libregex/lib.rs +++ b/src/libregex/lib.rs @@ -27,7 +27,7 @@ #![deny(missing_docs)] #[cfg(test)] -extern crate "test" as stdtest; +extern crate rustc_bench; #[cfg(test)] extern crate rand; diff --git a/src/libregex/test/bench.rs b/src/libregex/test/bench.rs index 17521ff7ea54b..69d7882da72d3 100644 --- a/src/libregex/test/bench.rs +++ b/src/libregex/test/bench.rs @@ -10,7 +10,7 @@ #![allow(non_snake_case)] use std::rand::{Rng, thread_rng}; -use stdtest::Bencher; +use rustc_bench::Bencher; use std::iter::repeat; use regex::{Regex, NoExpand}; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index a3a041c2497c7..375a13ae1a004 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -44,7 +44,7 @@ extern crate collections; extern crate "serialize" as rustc_serialize; // used by deriving #[cfg(test)] -extern crate test; +extern crate rustc_bench; pub use rustc_llvm as llvm; diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index f33971a6ac0c2..505fc75781329 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -651,8 +651,8 @@ mod tests { #[cfg(test)] mod bench { - extern crate test; - use self::test::Bencher; + extern crate rustc_bench; + use self::rustc_bench::Bencher; use super::{Sha256, FixedBuffer, Digest}; #[bench] diff --git a/src/librustc_bench/lib.rs b/src/librustc_bench/lib.rs new file mode 100644 index 0000000000000..b0c12983e83d7 --- /dev/null +++ b/src/librustc_bench/lib.rs @@ -0,0 +1,86 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Support code for rustc's built in micro-benchmarking framework. +//! +//! See the [Testing Guide](../guide-testing.html) for more details. + +#![crate_name = "rustc_bench"] +#![unstable] +#![crate_type = "rlib"] +#![crate_type = "dylib"] +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://doc.rust-lang.org/nightly/")] +#![feature(asm)] + +use std::time::Duration; + +/// 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`. +#[stable] +pub fn black_box(dummy: T) -> T { + // we need to "use" the argument in some way LLVM can't + // introspect. + unsafe {asm!("" : : "r"(&dummy))} + dummy +} + +/// Manager of the benchmarking runs. +/// +/// This is feed into functions marked with `#[bench]` to allow for +/// set-up & tear-down before running a piece of code repeatedly via a +/// call to `iter`. +#[stable] +#[allow(missing_copy_implementations)] +pub struct Bencher { + iterations: u64, + dur: Duration, + + /// A field to indicate the number of bytes that each iteration of the + /// benchmarking procedure consumed. When set to a nonzero value, the speed + /// of consumption can be printed in MB/s + #[stable] + pub bytes: u64, +} + +impl Bencher { + #[experimental] + pub fn new() -> Bencher { + Bencher { + iterations: 0, + dur: Duration::seconds(0), + bytes: 0, + } + } + + /// Callback for benchmark functions to run in their body. + #[stable] + pub fn iter(&mut self, mut inner: F) where F: FnMut() -> T { + self.dur = Duration::span(|| { + let k = self.iterations; + for _ in range(0u64, k) { + black_box(inner()); + } + }); + } + + #[experimental] + pub fn set_iterations(&mut self, n: u64) { self.iterations = n; } + + #[experimental] + pub fn iterations(&self) -> u64 { self.iterations } + + #[experimental] + pub fn dur(&self) -> Duration { self.dur } +} diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index d13d110320e17..b2b78406a2186 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -297,8 +297,8 @@ impl FromBase64 for [u8] { #[cfg(test)] mod tests { - extern crate test; - use self::test::Bencher; + extern crate rustc_bench; + use self::rustc_bench::Bencher; use base64::{Config, Newline, FromBase64, ToBase64, STANDARD, URL_SAFE}; #[test] diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index a11eb3f789875..947bdaf2d71bb 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -153,8 +153,8 @@ impl FromHex for str { #[cfg(test)] mod tests { - extern crate test; - use self::test::Bencher; + extern crate rustc_bench; + use self::rustc_bench::Bencher; use hex::{FromHex, ToHex}; #[test] diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index b7bf40a6ec52d..bc6960eeff50c 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2504,10 +2504,10 @@ impl FromStr for Json { #[cfg(test)] mod tests { - extern crate test; + extern crate rustc_bench; use self::Animal::*; use self::DecodeEnum::*; - use self::test::Bencher; + use self::rustc_bench::Bencher; use {Encodable, Decodable}; use super::Json::*; use super::ErrorCode::*; diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 139170fc012cb..8971bed1bab9c 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -28,7 +28,7 @@ Core encoding and decoding interfaces. #![cfg_attr(stage0, allow(unused_attributes))] // test harness access -#[cfg(test)] extern crate test; +#[cfg(test)] extern crate rustc_bench; #[macro_use] extern crate log; extern crate unicode; diff --git a/src/libstd/collections/hash/bench.rs b/src/libstd/collections/hash/bench.rs index 28689767cb0e3..fbfc537520bef 100644 --- a/src/libstd/collections/hash/bench.rs +++ b/src/libstd/collections/hash/bench.rs @@ -10,10 +10,9 @@ #![cfg(test)] -extern crate test; use prelude::v1::*; -use self::test::Bencher; +use rustc_bench::Bencher; use iter::{range_inclusive}; #[bench] diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 74c503e6f2ba8..9433bb51ee320 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -386,13 +386,12 @@ impl Writer for BufferedStream { #[cfg(test)] mod test { - extern crate test; use io; use prelude::v1::*; use super::*; use super::super::{IoResult, EndOfFile}; use super::super::mem::MemReader; - use self::test::Bencher; + use rustc_bench::Bencher; /// A type, free to create, primarily intended for benchmarking creation of /// wrappers that, just for construction, don't need a Reader/Writer that diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index af08eea210e7f..240cf872e61de 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -507,10 +507,8 @@ mod test { #[cfg(test)] mod bench { - extern crate test; - use prelude::v1::*; - use self::test::Bencher; + use rustc_bench::Bencher; // why is this a macro? wouldn't an inlined function work just as well? macro_rules! u64_from_be_bytes_bench_impl { diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 9a6ad04fdbc3e..22a6603879d2d 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -390,13 +390,12 @@ impl<'a> Buffer for BufReader<'a> { #[cfg(test)] mod test { - extern crate "test" as test_crate; - use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek}; - use prelude::v1::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt}; - use prelude::v1::{IteratorExt, Index}; + use prelude::v1::*; + + use io::{SeekSet, SeekCur, SeekEnd}; use io; use iter::repeat; - use self::test_crate::Bencher; + use rustc_bench::Bencher; use super::*; #[test] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index eef5bdb60eeaa..938ba4dd5007f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -115,9 +115,8 @@ #![deny(missing_docs)] -#[cfg(test)] -#[macro_use] -extern crate log; +#[cfg(test)] extern crate rustc_bench; +#[cfg(test)] #[macro_use] extern crate log; #[macro_use] #[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq, diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index f433cd1e66481..cf6d8525ceaa9 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -990,8 +990,7 @@ mod tests { #[cfg(test)] mod bench { - extern crate test; - use self::test::Bencher; + use rustc_bench::Bencher; use num::Int; use prelude::v1::*; diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 67fe599ecd6bf..7bfa5c33ca7c5 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -459,10 +459,8 @@ mod tests { #[cfg(test)] mod bench { - extern crate test; - mod uint { - use super::test::Bencher; + use rustc_bench::Bencher; use rand::{weak_rng, Rng}; use std::fmt; @@ -503,7 +501,7 @@ mod bench { } mod int { - use super::test::Bencher; + use rustc_bench::Bencher; use rand::{weak_rng, Rng}; use std::fmt; @@ -544,7 +542,7 @@ mod bench { } mod f64 { - use super::test::Bencher; + use rustc_bench::Bencher; use rand::{weak_rng, Rng}; use f64; diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 0b7dc19fcab4e..47bd9c2b90f93 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -1211,8 +1211,7 @@ mod tests { #[cfg(test)] mod bench { - extern crate test; - use self::test::Bencher; + use rustc_bench::Bencher; use super::*; use prelude::v1::{Clone, GenericPath}; diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index d3e6cd166ecf5..b92bf14c1ee9b 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -615,10 +615,9 @@ static RAND_BENCH_N: u64 = 100; #[cfg(test)] mod bench { - extern crate test; use prelude::v1::*; - use self::test::Bencher; + use rustc_bench::Bencher; use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N}; use super::{OsRng, weak_rng}; use mem::size_of; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 68d06cc4dab64..9a366ba8f8c09 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -37,6 +37,7 @@ extern crate regex; extern crate serialize; extern crate "serialize" as rustc_serialize; extern crate term; +extern crate rustc_bench; pub use self::TestFn::*; pub use self::MetricChange::*; @@ -55,7 +56,6 @@ use term::Terminal; use term::color::{Color, RED, YELLOW, GREEN, CYAN}; use std::any::Any; -use std::cmp; use std::collections::BTreeMap; use std::f64; use std::fmt::Show; @@ -71,11 +71,12 @@ use std::str::FromStr; use std::sync::mpsc::{channel, Sender}; use std::thread::{self, Thread}; use std::thunk::{Thunk, Invoke}; -use std::time::Duration; + +use rustc_bench::Bencher; // to be used by rustc to compile tests in libtest pub mod test { - pub use {Bencher, TestName, TestResult, TestDesc, + pub use {TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrIgnored, TrOk, Metric, MetricMap, MetricAdded, MetricRemoved, MetricChange, Improvement, Regression, LikelyNoise, @@ -180,18 +181,6 @@ impl fmt::Show for TestFn { } } -/// Manager of the benchmarking runs. -/// -/// This is feed into functions marked with `#[bench]` to allow for -/// set-up & tear-down before running a piece of code repeatedly via a -/// call to `iter`. -#[derive(Copy)] -pub struct Bencher { - iterations: u64, - dur: Duration, - pub bytes: u64, -} - #[derive(Copy, Clone, Show, PartialEq, Eq, Hash)] pub enum ShouldFail { No, @@ -1323,58 +1312,62 @@ impl MetricMap { // Benchmarking -/// 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`. -pub fn black_box(dummy: T) { - // we need to "use" the argument in some way LLVM can't - // introspect. - unsafe {asm!("" : : "r"(&dummy))} -} +pub mod bench { + use std::cmp; + use std::time::Duration; + use rustc_bench::Bencher; + use stats; + use super::BenchSamples; -impl Bencher { - /// Callback for benchmark functions to run in their body. - pub fn iter(&mut self, mut inner: F) where F: FnMut() -> T { - self.dur = Duration::span(|| { - let k = self.iterations; - for _ in range(0u64, k) { - black_box(inner()); - } - }); + pub fn benchmark(f: F) -> BenchSamples where F: FnMut(&mut Bencher) { + let mut bs = Bencher::new(); + + let ns_iter_summ = auto_bench(&mut bs, f); + + let ns_iter = cmp::max(ns_iter_summ.median as u64, 1); + let iter_s = 1_000_000_000 / ns_iter; + let mb_s = (bs.bytes * iter_s) / 1_000_000; + + BenchSamples { + ns_iter_summ: ns_iter_summ, + mb_s: mb_s as uint + } } - pub fn ns_elapsed(&mut self) -> u64 { - self.dur.num_nanoseconds().unwrap() as u64 + pub fn ns_elapsed(me: &mut Bencher) -> u64 { + me.dur().num_nanoseconds().unwrap() as u64 } - pub fn ns_per_iter(&mut self) -> u64 { - if self.iterations == 0 { + pub fn ns_per_iter(me: &mut Bencher) -> u64 { + if me.iterations() == 0 { 0 } else { - self.ns_elapsed() / cmp::max(self.iterations, 1) + ns_elapsed(me) / cmp::max(me.iterations(), 1) } } - pub fn bench_n(&mut self, n: u64, f: F) where F: FnOnce(&mut Bencher) { - self.iterations = n; - f(self); + pub fn bench_n(me: &mut Bencher, n: u64, f: F) + where F: FnOnce(&mut Bencher) + { + me.set_iterations(n); + f(me); } // This is a more statistics-driven benchmark algorithm - pub fn auto_bench(&mut self, mut f: F) -> stats::Summary where F: FnMut(&mut Bencher) { + pub fn auto_bench(me: &mut Bencher, mut f: F) -> stats::Summary + where F: FnMut(&mut Bencher) + { // Initial bench run to get ballpark figure. let mut n = 1_u64; - self.bench_n(n, |x| f(x)); + bench_n(me, n, |x| f(x)); // Try to estimate iter count for 1ms falling back to 1m // iterations if first run took < 1ns. - if self.ns_per_iter() == 0 { + if ns_per_iter(me) == 0 { n = 1_000_000; } else { - n = 1_000_000 / cmp::max(self.ns_per_iter(), 1); + n = 1_000_000 / cmp::max(ns_per_iter(me), 1); } // if the first run took more than 1ms we don't want to just // be left doing 0 iterations on every loop. The unfortunate @@ -1392,16 +1385,16 @@ impl Bencher { let loop_run = Duration::span(|| { for p in samples.iter_mut() { - self.bench_n(n, |x| f(x)); - *p = self.ns_per_iter() as f64; + bench_n(me, n, |x| f(x)); + *p = ns_per_iter(me) as f64; }; stats::winsorize(samples, 5.0); summ = Some(stats::Summary::new(samples)); for p in samples.iter_mut() { - self.bench_n(5 * n, |x| f(x)); - *p = self.ns_per_iter() as f64; + bench_n(me, 5 * n, |x| f(x)); + *p = ns_per_iter(me) as f64; }; stats::winsorize(samples, 5.0); @@ -1429,31 +1422,6 @@ impl Bencher { } } -pub mod bench { - use std::cmp; - use std::time::Duration; - use super::{Bencher, BenchSamples}; - - pub fn benchmark(f: F) -> BenchSamples where F: FnMut(&mut Bencher) { - let mut bs = Bencher { - iterations: 0, - dur: Duration::nanoseconds(0), - bytes: 0 - }; - - let ns_iter_summ = bs.auto_bench(f); - - let ns_iter = cmp::max(ns_iter_summ.median as u64, 1); - let iter_s = 1_000_000_000 / ns_iter; - let mb_s = (bs.bytes * iter_s) / 1_000_000; - - BenchSamples { - ns_iter_summ: ns_iter_summ, - mb_s: mb_s as uint - } - } -} - #[cfg(test)] mod tests { use test::{TrFailed, TrIgnored, TrOk, filter_tests, parse_opts, diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 1abb52459e493..f3c4193da972b 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -1057,7 +1057,7 @@ mod tests { #[cfg(test)] mod bench { - use Bencher; + use rustc_bench::Bencher; use stats::Stats; #[bench] diff --git a/src/test/compile-fail/view-items-at-top.rs b/src/test/compile-fail/view-items-at-top.rs index 7b78a8d932b33..7d290e065ef10 100644 --- a/src/test/compile-fail/view-items-at-top.rs +++ b/src/test/compile-fail/view-items-at-top.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate test; +extern crate rustc_bench; fn f() { } -use test::net; //~ ERROR `use` and `extern crate` declarations must precede items +use rustc_bench::net; //~ ERROR `use` and `extern crate` declarations must precede items fn main() { } diff --git a/src/test/run-pass/attr-before-view-item.rs b/src/test/run-pass/attr-before-view-item.rs index 2a65fd9d8a655..646d03f231c40 100644 --- a/src/test/run-pass/attr-before-view-item.rs +++ b/src/test/run-pass/attr-before-view-item.rs @@ -11,7 +11,7 @@ // error-pattern:expected item #[foo = "bar"] -extern crate test; +extern crate "std" as std2; pub fn main() { } diff --git a/src/test/run-pass/attr-before-view-item2.rs b/src/test/run-pass/attr-before-view-item2.rs index 5b8e62de6bd82..9b16a4c5a133d 100644 --- a/src/test/run-pass/attr-before-view-item2.rs +++ b/src/test/run-pass/attr-before-view-item2.rs @@ -12,7 +12,7 @@ mod m { #[foo = "bar"] - extern crate test; + extern crate std; } pub fn main() {