(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenchmark)
| 37 | } |
| 38 | |
| 39 | fn bench_cpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenchmark) { |
| 40 | pyo3::Python::attach(|py| { |
| 41 | let setup_name = format!("{}_setup", bench.name); |
| 42 | let setup_code = cpy_compile_code(py, &bench.setup, &setup_name).unwrap(); |
| 43 | |
| 44 | let code = cpy_compile_code(py, &bench.code, &bench.name).unwrap(); |
| 45 | |
| 46 | // Grab the exec function in advance so we don't have lookups in the hot code |
| 47 | let builtins = |
| 48 | pyo3::types::PyModule::import(py, "builtins").expect("Failed to import builtins"); |
| 49 | let exec = builtins.getattr("exec").expect("no exec in builtins"); |
| 50 | |
| 51 | let bench_func = |(globals, locals): &mut ( |
| 52 | pyo3::Bound<pyo3::types::PyDict>, |
| 53 | pyo3::Bound<pyo3::types::PyDict>, |
| 54 | )| { |
| 55 | let res = exec.call((&code, &*globals, &*locals), None); |
| 56 | if let Err(e) = res { |
| 57 | e.print(py); |
| 58 | panic!("Error running microbenchmark") |
| 59 | } |
| 60 | }; |
| 61 | |
| 62 | let bench_setup = |iterations| { |
| 63 | let globals = pyo3::types::PyDict::new(py); |
| 64 | let locals = pyo3::types::PyDict::new(py); |
| 65 | if let Some(idx) = iterations { |
| 66 | globals.set_item("ITERATIONS", idx).unwrap(); |
| 67 | } |
| 68 | |
| 69 | let res = exec.call((&setup_code, &globals, &locals), None); |
| 70 | if let Err(e) = res { |
| 71 | e.print(py); |
| 72 | panic!("Error running microbenchmark setup code") |
| 73 | } |
| 74 | (globals, locals) |
| 75 | }; |
| 76 | |
| 77 | if bench.iterate { |
| 78 | for idx in (100..=1_000).step_by(200) { |
| 79 | group.throughput(Throughput::Elements(idx as u64)); |
| 80 | group.bench_with_input(BenchmarkId::new("cpython", &bench.name), &idx, |b, idx| { |
| 81 | b.iter_batched_ref( |
| 82 | || bench_setup(Some(*idx)), |
| 83 | bench_func, |
| 84 | BatchSize::LargeInput, |
| 85 | ); |
| 86 | }); |
| 87 | } |
| 88 | } else { |
| 89 | group.bench_function(BenchmarkId::new("cpython", &bench.name), move |b| { |
| 90 | b.iter_batched_ref(|| bench_setup(None), bench_func, BatchSize::LargeInput); |
| 91 | }); |
| 92 | } |
| 93 | }) |
| 94 | } |
| 95 | |
| 96 | fn cpy_compile_code<'a>( |
no test coverage detected