| 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