Created
August 9, 2014 17:24
-
-
Save japaric/9bd316a6f53b2cefabba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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