Skip to content

Commit

Permalink
fixup benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Feb 5, 2024
1 parent e7276cc commit c45427e
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 18 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,
Bound, 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: &Bound<'_, 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 = &obj.as_borrowed();

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 = &collection.as_borrowed();

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 = &d.as_borrowed();

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 = &int.as_borrowed();

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 = &int.as_borrowed();

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 = &int.as_borrowed();

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 = &int.as_borrowed();

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 = &int.as_borrowed();

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 = &foo_module.as_borrowed();

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 = &foo_module.as_borrowed();

b.iter(|| {
for _ in 0..1000 {
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 = &py_dec.as_borrowed();

b.iter(|| {
let _: Decimal = black_box(py_dec).extract().unwrap();
Expand Down
13 changes: 9 additions & 4 deletions pyo3-benches/benches/bench_dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ 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 = &dict.as_borrowed();
let mut sum = 0;
b.iter(|| {
for (k, _v) in dict {
for (k, _v) in dict.iter() {
let i: u64 = k.extract().unwrap();
sum += i;
}
Expand All @@ -30,6 +31,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 = &dict.as_borrowed();
let mut sum = 0;
b.iter(|| {
for i in 0..LEN {
Expand All @@ -48,15 +50,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 = &dict.as_borrowed();
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 = &dict.as_borrowed();
b.iter(|| dict.extract::<BTreeMap<u64, u64>>());
});
}

Expand All @@ -65,7 +69,8 @@ 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 = &dict.as_borrowed();
b.iter(|| dict.extract::<hashbrown::HashMap<u64, u64>>());
});
}

Expand Down
13 changes: 9 additions & 4 deletions pyo3-benches/benches/bench_extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,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 = &d.as_borrowed();

bench.iter(|| match black_box(d).downcast::<PyString>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -51,7 +52,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.bind(py);

bench.iter(|| {
let v = black_box(int).extract::<i64>().unwrap();
Expand All @@ -63,6 +64,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 = &d.as_borrowed();

bench.iter(|| match black_box(d).extract::<i64>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -74,7 +76,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.bind(py);

bench.iter(|| {
let py_int = black_box(int).downcast::<PyInt>().unwrap();
Expand All @@ -87,6 +89,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 = &d.as_borrowed();

bench.iter(|| match black_box(d).downcast::<PyInt>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -98,7 +101,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.bind(py);

bench.iter(|| {
let v = black_box(float).extract::<f64>().unwrap();
Expand All @@ -110,6 +113,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 = &d.as_borrowed();

bench.iter(|| match black_box(d).extract::<f64>() {
Ok(v) => panic!("should err {}", v),
Expand All @@ -121,7 +125,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.bind(py);

bench.iter(|| {
let py_int = black_box(float).downcast::<PyFloat>().unwrap();
Expand All @@ -134,6 +138,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 = &d.as_borrowed();

bench.iter(|| match black_box(d).downcast::<PyFloat>() {
Ok(v) => panic!("should err {}", v),
Expand Down
2 changes: 1 addition & 1 deletion pyo3-benches/benches/bench_frompyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn not_a_list_via_extract_enum(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &Bound<'_, PyAny> = &PyString::new_bound(py, "foobar");

b.iter(|| match black_box(any).extract::<ListOrNotList<'_>>() {
b.iter(|| match black_box(&any).extract::<ListOrNotList<'_>>() {
Ok(ListOrNotList::List(_list)) => panic!(),
Ok(ListOrNotList::NotList(any)) => any,
Err(_) => panic!(),
Expand Down
4 changes: 2 additions & 2 deletions src/conversions/num_complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ macro_rules! complex_conversion {
unsafe {
let complex;
let obj = if obj.is_instance_of::<PyComplex>() {
obj.clone()
obj
} else if let Some(method) =
obj.lookup_special(crate::intern!(obj.py(), "__complex__"))?
{
Expand All @@ -161,7 +161,7 @@ macro_rules! complex_conversion {
// `obj` might still implement `__float__` or `__index__`, which will be
// handled by `PyComplex_{Real,Imag}AsDouble`, including propagating any
// errors if those methods don't exist / raise exceptions.
obj.clone()
obj
};
let ptr = obj.as_ptr();
let real = ffi::PyComplex_RealAsDouble(ptr);
Expand Down
6 changes: 3 additions & 3 deletions src/err/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,15 +840,15 @@ impl PyErrArguments for PyDowncastErrorArguments {
}

/// Convert `PyDowncastError` to Python `TypeError`.
impl<'a> std::convert::From<PyDowncastError<'a>> for PyErr {
impl std::convert::From<PyDowncastError<'_>> for PyErr {
fn from(err: PyDowncastError<'_>) -> PyErr {
PyErr::from(err.0)
}
}

impl<'a> std::error::Error for PyDowncastError<'a> {}
impl std::error::Error for PyDowncastError<'_> {}

impl<'a> std::fmt::Display for PyDowncastError<'a> {
impl std::fmt::Display for PyDowncastError<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
self.0.fmt(f)
}
Expand Down
11 changes: 10 additions & 1 deletion src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ impl<'py> Bound<'py, PyAny> {
) -> Option<Self> {
Py::from_borrowed_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj)))
}

/// Constructs a new Bound from a borrowed pointer, incrementing the reference count.
///
/// # Safety
/// ptr must be a valid pointer to a Python object.
pub unsafe fn from_borrowed_ptr_unchecked(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
Self::from_borrowed_ptr_or_opt(py, ptr).unwrap()
}
}

impl<'py, T> Bound<'py, T>
Expand Down Expand Up @@ -511,7 +519,8 @@ impl<'a, 'py> Borrowed<'a, 'py, PyAny> {
/// This is similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
/// the caller and it's the caller's responsibility to ensure that the reference this is
/// derived from is valid for the lifetime `'a`.
pub(crate) unsafe fn from_ptr_unchecked(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
#[doc(hidden)] // Used in macro code.
pub unsafe fn from_ptr_unchecked(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
Self(NonNull::new_unchecked(ptr), PhantomData, py)
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/invalid_result_conversion.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ error[E0277]: the trait bound `PyErr: From<MyError>` is not satisfied
| ^^^^^^^^^^^^^ the trait `From<MyError>` is not implemented for `PyErr`
|
= help: the following other types implement trait `From<T>`:
<PyErr as From<PyDowncastError<'_>>>
<PyErr as From<std::io::Error>>
<PyErr as From<PyBorrowError>>
<PyErr as From<PyBorrowMutError>>
<PyErr as From<PyDowncastError<'_>>>
<PyErr as From<DowncastError<'_, '_>>>
<PyErr as From<DowncastIntoError<'_>>>
<PyErr as From<NulError>>
Expand Down

0 comments on commit c45427e

Please sign in to comment.