Skip to content

Instantly share code, notes, and snippets.

@japaric
Created August 9, 2014 17:24
Show Gist options
  • Save japaric/9bd316a6f53b2cefabba to your computer and use it in GitHub Desktop.
Save japaric/9bd316a6f53b2cefabba to your computer and use it in GitHub Desktop.
pub struct Bencher;
impl Bencher {
pub fn iter<T>(&mut self, _: || -> T) {}
}
enum Routine<'a> {
Function(Option<|&mut Bencher|:'a>),
ExternalProgram,
}
// Here I want a closure that captures nothing, so I use `'static`
pub fn bench(routine: |&mut Bencher|:'static) {
benchmark_logic(Function(Some(routine)));
// ^~ error: mismatched types: expected
// `core::option::Option<|&mut Bencher|>` but found
// `core::option::Option<'static |&mut Bencher|:'static>` (expected no bounds but found
// `'static`)
// My solution (hack) (seems to work so far, nothing has exploded while I tested it)
//benchmark_logic(Function(Some(unsafe { std::mem::transmute(routine) })));
}
// Same as before, closure that captures nothing
pub fn bench_with_inputs<I>(routine: |&mut Bencher, &I|:'static, inputs: &[I]) {
for input in inputs.iter() {
benchmark_logic(Function(Some(|b| routine(b, input))));
// ^~~ error: mismatched types: expected
// `core::option::Option<|&mut Bencher|>` but found `core::option::Option<|&mut Bencher|>`
// (expected concrete lifetime, but found bound lifetime parameter )
// Hack again
//benchmark_logic(Function(Some(unsafe { std::mem::transmute(|b| routine(b, input)) })));
}
}
fn benchmark_logic(mut routine: Routine) {
match routine {
Function(ref mut fun_opt) => {
let fun = fun_opt.take_unwrap();
fun(&mut Bencher);
// (More logic here that calls `fun` a lot of times)
*fun_opt = Some(fun);
},
ExternalProgram => {
unimplemented!()
}
}
}
// run-pass test
fn main() {
// These two are equivalent
bench(routine);
bench(|b| {
println!("`from_elem(1024, 0)` via closure");
b.iter(|| Vec::from_elem(1024, 0u8))
});
// This is not valid usage and should not compile
// (This is the reason why the `bench` function take a 'static closure)
//let n = 1024;
//bench(|b| b.iter(|| Vec::from_elem(n, 0u8)));
// These two are equivalent
bench_with_inputs(routine_with_input, [1024, 2048, 4096]);
bench_with_inputs(|b, &n| {
println!("`from_elem({}, 0)` via closure", n);
b.iter(|| Vec::from_elem(n, 0u8))
}, [1024, 2048, 4096]);
}
fn routine(b: &mut Bencher) {
println!("`from_elem(1024, 0)`");
b.iter(|| Vec::from_elem(1024, 0u8));
}
fn routine_with_input(b: &mut Bencher, &n: &uint) {
println!("`from_elem({}, 0)`", n);
b.iter(|| Vec::from_elem(n, 0u8));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment