From 7d319a906e3a5173b2db1fddf239c21921297895 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 23 Mar 2024 20:17:33 +0000 Subject: [PATCH] ci: tidy up benchmarks a little (#3986) --- pyo3-benches/benches/bench_bigint.rs | 34 ++++-------- pyo3-benches/benches/bench_decimal.rs | 10 ++-- pyo3-benches/benches/bench_dict.rs | 10 ++-- pyo3-benches/benches/bench_extract.rs | 63 ++++++++-------------- pyo3-benches/benches/bench_frompyobject.rs | 50 +++++++---------- pyo3-benches/benches/bench_list.rs | 2 - pyo3-benches/benches/bench_set.rs | 23 +++++--- pyo3-benches/benches/bench_tuple.rs | 8 +-- 8 files changed, 81 insertions(+), 119 deletions(-) diff --git a/pyo3-benches/benches/bench_bigint.rs b/pyo3-benches/benches/bench_bigint.rs index 4a50b437d95..99635a70279 100644 --- a/pyo3-benches/benches/bench_bigint.rs +++ b/pyo3-benches/benches/bench_bigint.rs @@ -1,17 +1,18 @@ -use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; +use std::hint::black_box; + +use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; +use num_bigint::BigInt; use pyo3::prelude::*; use pyo3::types::PyDict; -use num_bigint::BigInt; - fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let d = PyDict::new_bound(py).into_any(); bench.iter(|| match black_box(&d).extract::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -20,10 +21,7 @@ fn extract_bigint_small(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let int = py.eval_bound("-42", None, None).unwrap(); - bench.iter(|| { - let v = black_box(&int).extract::().unwrap(); - black_box(v); - }); + bench.iter_with_large_drop(|| black_box(&int).extract::().unwrap()); }); } @@ -31,10 +29,7 @@ fn extract_bigint_big_negative(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let int = py.eval_bound("-10**300", None, None).unwrap(); - bench.iter(|| { - let v = black_box(&int).extract::().unwrap(); - black_box(v); - }); + bench.iter_with_large_drop(|| black_box(&int).extract::().unwrap()); }); } @@ -42,10 +37,7 @@ fn extract_bigint_big_positive(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let int = py.eval_bound("10**300", None, None).unwrap(); - bench.iter(|| { - let v = black_box(&int).extract::().unwrap(); - black_box(v); - }); + bench.iter_with_large_drop(|| black_box(&int).extract::().unwrap()); }); } @@ -53,10 +45,7 @@ fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let int = py.eval_bound("-10**3000", None, None).unwrap(); - bench.iter(|| { - let v = black_box(&int).extract::().unwrap(); - black_box(v); - }); + bench.iter_with_large_drop(|| black_box(&int).extract::().unwrap()); }); } @@ -64,10 +53,7 @@ fn extract_bigint_huge_positive(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let int = py.eval_bound("10**3000", None, None).unwrap(); - bench.iter(|| { - let v = black_box(&int).extract::().unwrap(); - black_box(v); - }); + bench.iter_with_large_drop(|| black_box(&int).extract::().unwrap()); }); } diff --git a/pyo3-benches/benches/bench_decimal.rs b/pyo3-benches/benches/bench_decimal.rs index 6db6704bf8e..53b79abbd38 100644 --- a/pyo3-benches/benches/bench_decimal.rs +++ b/pyo3-benches/benches/bench_decimal.rs @@ -1,8 +1,10 @@ -use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; +use std::hint::black_box; + +use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; +use rust_decimal::Decimal; use pyo3::prelude::*; use pyo3::types::PyDict; -use rust_decimal::Decimal; fn decimal_via_extract(b: &mut Bencher<'_>) { Python::with_gil(|py| { @@ -18,9 +20,7 @@ py_dec = decimal.Decimal("0.0") .unwrap(); let py_dec = locals.get_item("py_dec").unwrap().unwrap(); - b.iter(|| { - let _: Decimal = black_box(&py_dec).extract().unwrap(); - }); + b.iter(|| black_box(&py_dec).extract::().unwrap()); }) } diff --git a/pyo3-benches/benches/bench_dict.rs b/pyo3-benches/benches/bench_dict.rs index e6a1e2e6b0b..8c3dfe023c8 100644 --- a/pyo3-benches/benches/bench_dict.rs +++ b/pyo3-benches/benches/bench_dict.rs @@ -1,9 +1,10 @@ +use std::collections::{BTreeMap, HashMap}; +use std::hint::black_box; + use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::types::IntoPyDict; use pyo3::{prelude::*, types::PyMapping}; -use std::collections::{BTreeMap, HashMap}; -use std::hint::black_box; fn iter_dict(b: &mut Bencher<'_>) { Python::with_gil(|py| { @@ -69,7 +70,6 @@ fn extract_hashbrown_map(b: &mut Bencher<'_>) { }); } -#[cfg(not(codspeed))] fn mapping_from_dict(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; @@ -84,12 +84,10 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("dict_get_item", dict_get_item); c.bench_function("extract_hashmap", extract_hashmap); c.bench_function("extract_btreemap", extract_btreemap); + c.bench_function("mapping_from_dict", mapping_from_dict); #[cfg(feature = "hashbrown")] c.bench_function("extract_hashbrown_map", extract_hashbrown_map); - - #[cfg(not(codspeed))] - c.bench_function("mapping_from_dict", mapping_from_dict); } criterion_group!(benches, criterion_benchmark); diff --git a/pyo3-benches/benches/bench_extract.rs b/pyo3-benches/benches/bench_extract.rs index 434d8eb5b33..9bb7ef60ab4 100644 --- a/pyo3-benches/benches/bench_extract.rs +++ b/pyo3-benches/benches/bench_extract.rs @@ -1,4 +1,6 @@ -use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; +use std::hint::black_box; + +use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::{ prelude::*, @@ -7,9 +9,9 @@ use pyo3::{ fn extract_str_extract_success(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let s = &PyString::new_bound(py, "Hello, World!"); + let s = PyString::new_bound(py, "Hello, World!").into_any(); - bench.iter(|| black_box(s).extract::<&str>().unwrap()); + bench.iter(|| black_box(&s).extract::<&str>().unwrap()); }); } @@ -19,7 +21,7 @@ fn extract_str_extract_fail(bench: &mut Bencher<'_>) { bench.iter(|| match black_box(&d).extract::<&str>() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -27,10 +29,10 @@ fn extract_str_extract_fail(bench: &mut Bencher<'_>) { #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] fn extract_str_downcast_success(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let s = &PyString::new_bound(py, "Hello, World!"); + let s = PyString::new_bound(py, "Hello, World!").into_any(); bench.iter(|| { - let py_str = black_box(s).downcast::().unwrap(); + let py_str = black_box(&s).downcast::().unwrap(); py_str.to_str().unwrap() }); }); @@ -42,20 +44,16 @@ fn extract_str_downcast_fail(bench: &mut Bencher<'_>) { bench.iter(|| match black_box(&d).downcast::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } fn extract_int_extract_success(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int_obj: PyObject = 123.into_py(py); - let int = int_obj.as_ref(py); + let int = 123.to_object(py).into_bound(py); - bench.iter(|| { - let v = black_box(int).extract::().unwrap(); - black_box(v); - }); + bench.iter(|| black_box(&int).extract::().unwrap()); }); } @@ -65,26 +63,22 @@ fn extract_int_extract_fail(bench: &mut Bencher<'_>) { bench.iter(|| match black_box(&d).extract::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } -#[cfg(not(codspeed))] fn extract_int_downcast_success(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int_obj: PyObject = 123.into_py(py); - let int = int_obj.as_ref(py); + let int = 123.to_object(py).into_bound(py); bench.iter(|| { - let py_int = black_box(int).downcast::().unwrap(); - let v = py_int.extract::().unwrap(); - black_box(v); + let py_int = black_box(&int).downcast::().unwrap(); + py_int.extract::().unwrap() }); }); } -#[cfg(not(codspeed))] fn extract_int_downcast_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { let d = PyDict::new_bound(py).into_any(); @@ -96,16 +90,11 @@ fn extract_int_downcast_fail(bench: &mut Bencher<'_>) { }); } -#[cfg(not(codspeed))] fn extract_float_extract_success(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let float_obj: PyObject = 23.42.into_py(py); - let float = float_obj.as_ref(py); + let float = 23.42.to_object(py).into_bound(py); - bench.iter(|| { - let v = black_box(float).extract::().unwrap(); - black_box(v); - }); + bench.iter(|| black_box(&float).extract::().unwrap()); }); } @@ -115,21 +104,18 @@ fn extract_float_extract_fail(bench: &mut Bencher<'_>) { bench.iter(|| match black_box(&d).extract::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } -#[cfg(not(codspeed))] fn extract_float_downcast_success(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let float_obj: PyObject = 23.42.into_py(py); - let float = float_obj.as_ref(py); + let float = 23.42.to_object(py).into_bound(py); bench.iter(|| { - let py_int = black_box(float).downcast::().unwrap(); - let v = py_int.extract::().unwrap(); - black_box(v); + let py_float = black_box(&float).downcast::().unwrap(); + py_float.value() }); }); } @@ -140,7 +126,7 @@ fn extract_float_downcast_fail(bench: &mut Bencher<'_>) { bench.iter(|| match black_box(&d).downcast::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -151,20 +137,15 @@ fn criterion_benchmark(c: &mut Criterion) { #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] c.bench_function("extract_str_downcast_success", extract_str_downcast_success); c.bench_function("extract_str_downcast_fail", extract_str_downcast_fail); - #[cfg(not(codspeed))] c.bench_function("extract_int_extract_success", extract_int_extract_success); c.bench_function("extract_int_extract_fail", extract_int_extract_fail); - #[cfg(not(codspeed))] c.bench_function("extract_int_downcast_success", extract_int_downcast_success); - #[cfg(not(codspeed))] c.bench_function("extract_int_downcast_fail", extract_int_downcast_fail); - #[cfg(not(codspeed))] c.bench_function( "extract_float_extract_success", extract_float_extract_success, ); c.bench_function("extract_float_extract_fail", extract_float_extract_fail); - #[cfg(not(codspeed))] c.bench_function( "extract_float_downcast_success", extract_float_downcast_success, diff --git a/pyo3-benches/benches/bench_frompyobject.rs b/pyo3-benches/benches/bench_frompyobject.rs index e78c48fcaa1..f53f116a154 100644 --- a/pyo3-benches/benches/bench_frompyobject.rs +++ b/pyo3-benches/benches/bench_frompyobject.rs @@ -1,11 +1,14 @@ -use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; +use std::hint::black_box; + +use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::{ prelude::*, - types::{PyFloat, PyList, PyString}, + types::{PyList, PyString}, }; #[derive(FromPyObject)] +#[allow(dead_code)] enum ManyTypes { Int(i32), Bytes(Vec), @@ -14,44 +17,41 @@ enum ManyTypes { fn enum_from_pyobject(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let any: &Bound<'_, PyAny> = &PyString::new_bound(py, "hello world"); + let any = PyString::new_bound(py, "hello world").into_any(); - b.iter(|| any.extract::().unwrap()); + b.iter(|| black_box(&any).extract::().unwrap()); }) } -#[cfg(not(codspeed))] fn list_via_downcast(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let any: &Bound<'_, PyAny> = &PyList::empty_bound(py); + let any = PyList::empty_bound(py).into_any(); - b.iter(|| black_box(any).downcast::().unwrap()); + b.iter(|| black_box(&any).downcast::().unwrap()); }) } -#[cfg(not(codspeed))] fn list_via_extract(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let any: &Bound<'_, PyAny> = &PyList::empty_bound(py); + let any = PyList::empty_bound(py).into_any(); - b.iter(|| black_box(any).extract::>().unwrap()); + b.iter(|| black_box(&any).extract::>().unwrap()); }) } -#[cfg(not(codspeed))] fn not_a_list_via_downcast(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let any: &Bound<'_, PyAny> = &PyString::new_bound(py, "foobar"); + let any = PyString::new_bound(py, "foobar").into_any(); - b.iter(|| black_box(any).downcast::().unwrap_err()); + b.iter(|| black_box(&any).downcast::().unwrap_err()); }) } fn not_a_list_via_extract(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let any: &Bound<'_, PyAny> = &PyString::new_bound(py, "foobar"); + let any = PyString::new_bound(py, "foobar").into_any(); - b.iter(|| black_box(any).extract::>().unwrap_err()); + b.iter(|| black_box(&any).extract::>().unwrap_err()); }) } @@ -63,9 +63,9 @@ enum ListOrNotList<'a> { fn not_a_list_via_extract_enum(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let any: &Bound<'_, PyAny> = &PyString::new_bound(py, "foobar"); + let any = PyString::new_bound(py, "foobar").into_any(); - b.iter(|| match black_box(any).extract::>() { + b.iter(|| match black_box(&any).extract::>() { Ok(ListOrNotList::List(_list)) => panic!(), Ok(ListOrNotList::NotList(any)) => any, Err(_) => panic!(), @@ -73,26 +73,16 @@ fn not_a_list_via_extract_enum(b: &mut Bencher<'_>) { }) } -#[cfg(not(codspeed))] -fn f64_from_pyobject(b: &mut Bencher<'_>) { - Python::with_gil(|py| { - let obj = &PyFloat::new_bound(py, 1.234); - b.iter(|| black_box(obj).extract::().unwrap()); - }) -} - fn criterion_benchmark(c: &mut Criterion) { c.bench_function("enum_from_pyobject", enum_from_pyobject); - #[cfg(not(codspeed))] + c.bench_function("list_via_downcast", list_via_downcast); - #[cfg(not(codspeed))] + c.bench_function("list_via_extract", list_via_extract); - #[cfg(not(codspeed))] + c.bench_function("not_a_list_via_downcast", not_a_list_via_downcast); c.bench_function("not_a_list_via_extract", not_a_list_via_extract); c.bench_function("not_a_list_via_extract_enum", not_a_list_via_extract_enum); - #[cfg(not(codspeed))] - c.bench_function("f64_from_pyobject", f64_from_pyobject); } criterion_group!(benches, criterion_benchmark); diff --git a/pyo3-benches/benches/bench_list.rs b/pyo3-benches/benches/bench_list.rs index 774dddcea38..dcbdb4779cb 100644 --- a/pyo3-benches/benches/bench_list.rs +++ b/pyo3-benches/benches/bench_list.rs @@ -55,7 +55,6 @@ fn list_get_item_unchecked(b: &mut Bencher<'_>) { }); } -#[cfg(not(codspeed))] fn sequence_from_list(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 50_000; @@ -70,7 +69,6 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("list_get_item", list_get_item); #[cfg(not(Py_LIMITED_API))] c.bench_function("list_get_item_unchecked", list_get_item_unchecked); - #[cfg(not(codspeed))] c.bench_function("sequence_from_list", sequence_from_list); } diff --git a/pyo3-benches/benches/bench_set.rs b/pyo3-benches/benches/bench_set.rs index b04cb491304..18134a15bd5 100644 --- a/pyo3-benches/benches/bench_set.rs +++ b/pyo3-benches/benches/bench_set.rs @@ -2,7 +2,10 @@ use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criter use pyo3::prelude::*; use pyo3::types::PySet; -use std::collections::{BTreeSet, HashSet}; +use std::{ + collections::{BTreeSet, HashSet}, + hint::black_box, +}; fn set_new(b: &mut Bencher<'_>) { Python::with_gil(|py| { @@ -31,16 +34,20 @@ fn iter_set(b: &mut Bencher<'_>) { fn extract_hashset(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let set = PySet::new_bound(py, &(0..LEN).collect::>()).unwrap(); - b.iter_with_large_drop(|| HashSet::::extract(set.as_gil_ref())); + let any = PySet::new_bound(py, &(0..LEN).collect::>()) + .unwrap() + .into_any(); + b.iter_with_large_drop(|| black_box(&any).extract::>()); }); } fn extract_btreeset(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let set = PySet::new_bound(py, &(0..LEN).collect::>()).unwrap(); - b.iter_with_large_drop(|| BTreeSet::::extract(set.as_gil_ref())); + let any = PySet::new_bound(py, &(0..LEN).collect::>()) + .unwrap() + .into_any(); + b.iter_with_large_drop(|| black_box(&any).extract::>()); }); } @@ -48,8 +55,10 @@ fn extract_btreeset(b: &mut Bencher<'_>) { fn extract_hashbrown_set(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let set = PySet::new_bound(py, &(0..LEN).collect::>()).unwrap(); - b.iter_with_large_drop(|| hashbrown::HashSet::::extract(set.as_gil_ref())); + let any = PySet::new_bound(py, &(0..LEN).collect::>()) + .unwrap() + .into_any(); + b.iter_with_large_drop(|| black_box(&any).extract::>()); }); } diff --git a/pyo3-benches/benches/bench_tuple.rs b/pyo3-benches/benches/bench_tuple.rs index 22bf7588ed1..3c0b56a0234 100644 --- a/pyo3-benches/benches/bench_tuple.rs +++ b/pyo3-benches/benches/bench_tuple.rs @@ -1,3 +1,5 @@ +use std::hint::black_box; + use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::prelude::*; @@ -89,12 +91,11 @@ fn tuple_get_borrowed_item_unchecked(b: &mut Bencher<'_>) { }); } -#[cfg(not(codspeed))] fn sequence_from_tuple(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 50_000; - let tuple = PyTuple::new_bound(py, 0..LEN).to_object(py); - b.iter(|| tuple.downcast::(py).unwrap()); + let tuple = PyTuple::new_bound(py, 0..LEN).into_any(); + b.iter(|| black_box(&tuple).downcast::().unwrap()); }); } @@ -132,7 +133,6 @@ fn criterion_benchmark(c: &mut Criterion) { "tuple_get_borrowed_item_unchecked", tuple_get_borrowed_item_unchecked, ); - #[cfg(not(codspeed))] c.bench_function("sequence_from_tuple", sequence_from_tuple); c.bench_function("tuple_new_list", tuple_new_list); c.bench_function("tuple_to_list", tuple_to_list);