-
Notifications
You must be signed in to change notification settings - Fork 904
Closed
Description
Bug Description
extracting an int is extremely slow when it fails.
Benchmarks:
test extract_int_downcast_fail ... bench: 1 ns/iter (+/- 0)
test extract_int_downcast_success ... bench: 7 ns/iter (+/- 0)
test extract_int_extract_fail ... bench: 114 ns/iter (+/- 8) 😱
test extract_int_extract_success ... bench: 7 ns/iter (+/- 0)
test extract_str_downcast_fail ... bench: 1 ns/iter (+/- 0)
test extract_str_downcast_success ... bench: 3 ns/iter (+/- 0)
test extract_str_extract_fail ... bench: 23 ns/iter (+/- 0)
test extract_str_extract_success ... bench: 4 ns/iter (+/- 0)
I'm suggesting this difference is big enough to count as a bug, but happy to be corrected.
Steps to Reproduce
Benchmark Code
#[bench]
fn extract_str_extract_success(bench: &mut Bencher) {
Python::with_gil(|py| {
let s = PyString::new(py, "Hello, World!") as &PyAny;
bench.iter(|| {
let v = black_box(s).extract::<&str>().unwrap();
black_box(v);
});
});
}
#[bench]
fn extract_str_extract_fail(bench: &mut Bencher) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
bench.iter(|| {
match black_box(d).extract::<&str>() {
Ok(v) => panic!("should err {}", v),
Err(e) => black_box(e),
}
});
});
}
#[bench]
fn extract_str_downcast_success(bench: &mut Bencher) {
Python::with_gil(|py| {
let s = PyString::new(py, "Hello, World!") as &PyAny;
bench.iter(|| {
let py_str = black_box(s).downcast::<PyString>().unwrap();
let v = py_str.to_str().unwrap();
black_box(v);
});
});
}
#[bench]
fn extract_str_downcast_fail(bench: &mut Bencher) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
bench.iter(|| {
match black_box(d).downcast::<PyString>() {
Ok(v) => panic!("should err {}", v),
Err(e) => black_box(e),
}
});
});
}
#[bench]
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);
bench.iter(|| {
let v = black_box(int).extract::<i64>().unwrap();
black_box(v);
});
});
}
#[bench]
fn extract_int_extract_fail(bench: &mut Bencher) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
bench.iter(|| {
match black_box(d).extract::<i64>() {
Ok(v) => panic!("should err {}", v),
Err(e) => black_box(e),
}
});
});
}
#[bench]
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);
bench.iter(|| {
let py_int = black_box(int).downcast::<PyInt>().unwrap();
let v = py_int.extract::<i64>().unwrap();
black_box(v);
});
});
}
#[bench]
fn extract_int_downcast_fail(bench: &mut Bencher) {
Python::with_gil(|py| {
let d = PyDict::new(py) as &PyAny;
bench.iter(|| {
match black_box(d).downcast::<PyInt>() {
Ok(v) => panic!("should err {}", v),
Err(e) => black_box(e),
}
});
});
}Backtrace
naYour operating system and version
MacOS
Your Python version (python --version)
Python 3.10.5
Your Rust version (rustc --version)
rustc 1.68.0-nightly (4781233a7 2023-01-16)
Your PyO3 version
0.18.3
How did you install python? Did you use a virtualenv?
pyenv
Additional Info
No response
Metadata
Metadata
Assignees
Labels
No labels