Skip to content

Commit

Permalink
fixup benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Dec 5, 2023
1 parent d9dd934 commit d4baf2a
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 30 deletions.
7 changes: 5 additions & 2 deletions pyo3-benches/benches/bench_any.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion};

use pyo3::prelude::*;
use pyo3::{
types::{
PyBool, PyByteArray, PyBytes, PyDict, PyFloat, PyFrozenSet, PyInt, PyList, PyMapping,
PySequence, PySet, PyString, PyTuple,
},
PyAny, PyResult, Python,
Py2, PyAny, PyResult, Python,
};

#[derive(PartialEq, Eq, Debug)]
Expand All @@ -27,7 +28,7 @@ enum ObjectType {
Unknown,
}

fn find_object_type(obj: &PyAny) -> ObjectType {
fn find_object_type(obj: &Py2<'_, PyAny>) -> ObjectType {
if obj.is_none() {
ObjectType::None
} else if obj.is_instance_of::<PyBool>() {
Expand Down Expand Up @@ -64,6 +65,7 @@ fn find_object_type(obj: &PyAny) -> ObjectType {
fn bench_identify_object_type(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let obj = py.eval("object()", None, None).unwrap();
let obj = Py2::borrowed_from_gil_ref(&obj);

b.iter(|| find_object_type(obj));

Expand All @@ -74,6 +76,7 @@ fn bench_identify_object_type(b: &mut Bencher<'_>) {
fn bench_collect_generic_iterator(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let collection = py.eval("list(range(1 << 20))", None, None).unwrap();
let collection = Py2::<PyAny>::borrowed_from_gil_ref(&collection);

b.iter(|| {
collection
Expand Down
7 changes: 7 additions & 0 deletions pyo3-benches/benches/bench_bigint.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion};

use pyo3::prelude::*;
use pyo3::{types::PyDict, PyAny, Python};

use num_bigint::BigInt;

fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
let d = Py2::borrowed_from_gil_ref(&d);

bench.iter(|| match black_box(d).extract::<BigInt>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -18,6 +20,7 @@ fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) {
fn extract_bigint_small(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let int = py.eval("-42", None, None).unwrap();
let int = Py2::borrowed_from_gil_ref(&int);

bench.iter(|| {
let v = black_box(int).extract::<BigInt>().unwrap();
Expand All @@ -29,6 +32,7 @@ fn extract_bigint_small(bench: &mut Bencher<'_>) {
fn extract_bigint_big_negative(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let int = py.eval("-10**300", None, None).unwrap();
let int = Py2::borrowed_from_gil_ref(&int);

bench.iter(|| {
let v = black_box(int).extract::<BigInt>().unwrap();
Expand All @@ -40,6 +44,7 @@ fn extract_bigint_big_negative(bench: &mut Bencher<'_>) {
fn extract_bigint_big_positive(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let int = py.eval("10**300", None, None).unwrap();
let int = Py2::borrowed_from_gil_ref(&int);

bench.iter(|| {
let v = black_box(int).extract::<BigInt>().unwrap();
Expand All @@ -51,6 +56,7 @@ fn extract_bigint_big_positive(bench: &mut Bencher<'_>) {
fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let int = py.eval("-10**3000", None, None).unwrap();
let int = Py2::borrowed_from_gil_ref(&int);

bench.iter(|| {
let v = black_box(int).extract::<BigInt>().unwrap();
Expand All @@ -62,6 +68,7 @@ fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) {
fn extract_bigint_huge_positive(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let int = py.eval("10**3000", None, None).unwrap();
let int = Py2::borrowed_from_gil_ref(&int);

bench.iter(|| {
let v = black_box(int).extract::<BigInt>().unwrap();
Expand Down
2 changes: 2 additions & 0 deletions pyo3-benches/benches/bench_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ fn bench_call_0(b: &mut Bencher<'_>) {
let module = test_module!(py, "def foo(): pass");

let foo_module = module.getattr("foo").unwrap();
let foo_module = Py2::borrowed_from_gil_ref(&foo_module);

b.iter(|| {
for _ in 0..1000 {
Expand All @@ -34,6 +35,7 @@ class Foo:
);

let foo_module = module.getattr("Foo").unwrap().call0().unwrap();
let foo_module = Py2::borrowed_from_gil_ref(&foo_module);

b.iter(|| {
for _ in 0..1000 {
Expand Down
28 changes: 20 additions & 8 deletions pyo3-benches/benches/bench_comparisons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,31 @@ impl OrderedRichcmp {

fn bench_ordered_dunder_methods(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let obj1 = Py::new(py, OrderedDunderMethods(0)).unwrap().into_ref(py);
let obj2 = Py::new(py, OrderedDunderMethods(1)).unwrap().into_ref(py);

b.iter(|| obj2.gt(obj1).unwrap());
let obj1 = Py::new(py, OrderedDunderMethods(0))
.unwrap()
.attach_into(py)
.into_any();
let obj2 = Py::new(py, OrderedDunderMethods(1))
.unwrap()
.attach_into(py)
.into_any();

b.iter(|| obj2.gt(&obj1).unwrap());
});
}

fn bench_ordered_richcmp(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let obj1 = Py::new(py, OrderedRichcmp(0)).unwrap().into_ref(py);
let obj2 = Py::new(py, OrderedRichcmp(1)).unwrap().into_ref(py);

b.iter(|| obj2.gt(obj1).unwrap());
let obj1 = Py::new(py, OrderedRichcmp(0))
.unwrap()
.attach_into(py)
.into_any();
let obj2 = Py::new(py, OrderedRichcmp(1))
.unwrap()
.attach_into(py)
.into_any();

b.iter(|| obj2.gt(&obj1).unwrap());
});
}

Expand Down
1 change: 1 addition & 0 deletions pyo3-benches/benches/bench_decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ py_dec = decimal.Decimal("0.0")
)
.unwrap();
let py_dec = locals.get_item("py_dec").unwrap().unwrap();
let py_dec = Py2::borrowed_from_gil_ref(&py_dec);

b.iter(|| {
let _: Decimal = black_box(py_dec).extract().unwrap();
Expand Down
21 changes: 12 additions & 9 deletions pyo3-benches/benches/bench_dict.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion};

use pyo3::types::IntoPyDict;
use pyo3::types::{IntoPyDict, PyDict};
use pyo3::{prelude::*, types::PyMapping};
use std::collections::{BTreeMap, HashMap};

fn iter_dict(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
const LEN: usize = 100_000;
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
let dict = Py2::<PyDict>::borrowed_from_gil_ref(&dict);
let mut sum = 0;
b.iter(|| {
for (k, _v) in dict {
Expand All @@ -29,6 +30,7 @@ fn dict_get_item(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
const LEN: usize = 50_000;
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
let dict = Py2::<PyDict>::borrowed_from_gil_ref(&dict);
let mut sum = 0;
b.iter(|| {
for i in 0..LEN {
Expand All @@ -47,15 +49,17 @@ fn extract_hashmap(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
const LEN: usize = 100_000;
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
b.iter(|| HashMap::<u64, u64>::extract(dict));
let dict = Py2::<PyDict>::borrowed_from_gil_ref(&dict);
b.iter(|| dict.extract::<HashMap<u64, u64>>());
});
}

fn extract_btreemap(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
const LEN: usize = 100_000;
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
b.iter(|| BTreeMap::<u64, u64>::extract(dict));
let dict = Py2::<PyDict>::borrowed_from_gil_ref(&dict);
b.iter(|| dict.extract::<BTreeMap<u64, u64>>());
});
}

Expand All @@ -64,19 +68,18 @@ fn extract_hashbrown_map(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
const LEN: usize = 100_000;
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
b.iter(|| hashbrown::HashMap::<u64, u64>::extract(dict));
let dict = Py2::<PyDict>::borrowed_from_gil_ref(&dict);
b.iter(|| dict.extract::<hashbrown::HashMap<u64, u64>>());
});
}

fn mapping_from_dict(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
const LEN: usize = 100_000;
let dict = (0..LEN as u64)
.map(|i| (i, i * 2))
.into_py_dict(py)
.to_object(py);
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
let dict = Py2::<PyDict>::borrowed_from_gil_ref(&dict);
b.iter(|| {
let _: &PyMapping = dict.extract(py).unwrap();
let _ = dict.downcast::<PyMapping>().unwrap();
});
});
}
Expand Down
15 changes: 11 additions & 4 deletions pyo3-benches/benches/bench_extract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion};

use pyo3::{
prelude::*,
types::{PyDict, PyFloat, PyInt, PyString},
IntoPy, PyAny, PyObject, Python,
};
Expand Down Expand Up @@ -30,6 +31,7 @@ fn extract_str_extract_fail(bench: &mut Bencher<'_>) {
fn extract_str_downcast_success(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let s = PyString::new(py, "Hello, World!") as &PyAny;
let s = Py2::borrowed_from_gil_ref(&s);

bench.iter(|| {
let py_str = black_box(s).downcast::<PyString>().unwrap();
Expand All @@ -42,6 +44,7 @@ fn extract_str_downcast_success(bench: &mut Bencher<'_>) {
fn extract_str_downcast_fail(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
let d = Py2::borrowed_from_gil_ref(&d);

bench.iter(|| match black_box(d).downcast::<PyString>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -53,7 +56,7 @@ fn extract_str_downcast_fail(bench: &mut Bencher<'_>) {
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 = int_obj.attach(py);

bench.iter(|| {
let v = black_box(int).extract::<i64>().unwrap();
Expand All @@ -65,6 +68,7 @@ fn extract_int_extract_success(bench: &mut Bencher<'_>) {
fn extract_int_extract_fail(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
let d = Py2::borrowed_from_gil_ref(&d);

bench.iter(|| match black_box(d).extract::<i64>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -76,7 +80,7 @@ fn extract_int_extract_fail(bench: &mut Bencher<'_>) {
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 = int_obj.attach(py);

bench.iter(|| {
let py_int = black_box(int).downcast::<PyInt>().unwrap();
Expand All @@ -89,6 +93,7 @@ fn extract_int_downcast_success(bench: &mut Bencher<'_>) {
fn extract_int_downcast_fail(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
let d = Py2::borrowed_from_gil_ref(&d);

bench.iter(|| match black_box(d).downcast::<PyInt>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -100,7 +105,7 @@ fn extract_int_downcast_fail(bench: &mut Bencher<'_>) {
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 = float_obj.attach(py);

bench.iter(|| {
let v = black_box(float).extract::<f64>().unwrap();
Expand All @@ -112,6 +117,7 @@ fn extract_float_extract_success(bench: &mut Bencher<'_>) {
fn extract_float_extract_fail(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
let d = Py2::borrowed_from_gil_ref(&d);

bench.iter(|| match black_box(d).extract::<f64>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -123,7 +129,7 @@ fn extract_float_extract_fail(bench: &mut Bencher<'_>) {
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 = float_obj.attach(py);

bench.iter(|| {
let py_int = black_box(float).downcast::<PyFloat>().unwrap();
Expand All @@ -136,6 +142,7 @@ fn extract_float_downcast_success(bench: &mut Bencher<'_>) {
fn extract_float_downcast_fail(bench: &mut Bencher<'_>) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
let d = Py2::borrowed_from_gil_ref(&d);

bench.iter(|| match black_box(d).downcast::<PyFloat>() {
Ok(v) => panic!("should err {}", v),
Expand Down
11 changes: 9 additions & 2 deletions pyo3-benches/benches/bench_frompyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum ManyTypes {
fn enum_from_pyobject(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let obj = PyString::new(py, "hello world");
let obj = Py2::<PyString>::borrowed_from_gil_ref(&obj);
b.iter(|| {
let _: ManyTypes = obj.extract().unwrap();
});
Expand All @@ -24,26 +25,29 @@ fn enum_from_pyobject(b: &mut Bencher<'_>) {
fn list_via_downcast(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyList::empty(py).into();
let any = Py2::borrowed_from_gil_ref(&any);

b.iter(|| {
let _list: &PyList = black_box(any).downcast().unwrap();
let _list = black_box(any).downcast::<PyList>().unwrap();
});
})
}

fn list_via_extract(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyList::empty(py).into();
let any = Py2::borrowed_from_gil_ref(&any);

b.iter(|| {
let _list: &PyList = black_box(any).extract().unwrap();
let _list: Py2<'_, PyList> = black_box(any).extract().unwrap();
});
})
}

fn not_a_list_via_downcast(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyString::new(py, "foobar").into();
let any = Py2::borrowed_from_gil_ref(&any);

b.iter(|| {
black_box(any).downcast::<PyList>().unwrap_err();
Expand All @@ -54,6 +58,7 @@ fn not_a_list_via_downcast(b: &mut Bencher<'_>) {
fn not_a_list_via_extract(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyString::new(py, "foobar").into();
let any = Py2::borrowed_from_gil_ref(&any);

b.iter(|| {
black_box(any).extract::<&PyList>().unwrap_err();
Expand All @@ -70,6 +75,7 @@ enum ListOrNotList<'a> {
fn not_a_list_via_extract_enum(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyString::new(py, "foobar").into();
let any = Py2::borrowed_from_gil_ref(&any);

b.iter(|| match black_box(any).extract::<ListOrNotList<'_>>() {
Ok(ListOrNotList::List(_list)) => panic!(),
Expand All @@ -82,6 +88,7 @@ fn not_a_list_via_extract_enum(b: &mut Bencher<'_>) {
fn f64_from_pyobject(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let obj = PyFloat::new(py, 1.234);
let obj = Py2::<PyFloat>::borrowed_from_gil_ref(&obj);
b.iter(|| {
let _: f64 = obj.extract().unwrap();
});
Expand Down
Loading

0 comments on commit d4baf2a

Please sign in to comment.