From 6c3f688a604962d38384ef90626af5f1fa1442d4 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 6 Jun 2021 16:19:29 +0200 Subject: [PATCH] Add more argument parsing benchmarks. Change output so that benchmarks belonging together are shown together. --- examples/pyo3-benchmarks/src/lib.rs | 74 ++++++---- .../pyo3-benchmarks/tests/test_benchmarks.py | 126 +++++++++++------- examples/pyo3-benchmarks/tox.ini | 2 +- 3 files changed, 130 insertions(+), 72 deletions(-) diff --git a/examples/pyo3-benchmarks/src/lib.rs b/examples/pyo3-benchmarks/src/lib.rs index 6e55c6ae..0f216ed5 100644 --- a/examples/pyo3-benchmarks/src/lib.rs +++ b/examples/pyo3-benchmarks/src/lib.rs @@ -2,38 +2,66 @@ use pyo3::prelude::*; use pyo3::types::{PyDict, PyTuple}; use pyo3::wrap_pyfunction; +#[pyfunction] +fn none() {} + +#[pyfunction(b = "\"bar\"", "*", c = "None")] +fn simple<'a>(a: i32, b: &'a str, c: Option<&'a PyDict>) -> (i32, &'a str, Option<&'a PyDict>) { + (a, b, c) +} + +#[pyfunction(b = "\"bar\"", args = "*", c = "None")] +fn simple_args<'a>( + a: i32, + b: &'a str, + c: Option<&'a PyDict>, + args: &'a PyTuple, +) -> (i32, &'a str, &'a PyTuple, Option<&'a PyDict>) { + (a, b, args, c) +} + +#[pyfunction(b = "\"bar\"", c = "None", kwargs = "**")] +fn simple_kwargs<'a>( + a: i32, + b: &'a str, + c: Option<&'a PyDict>, + kwargs: Option<&'a PyDict>, +) -> (i32, &'a str, Option<&'a PyDict>, Option<&'a PyDict>) { + (a, b, c, kwargs) +} + +#[pyfunction(a, b = "\"bar\"", args = "*", c = "None", kwargs = "**")] +fn simple_args_kwargs<'a>( + a: i32, + b: &'a str, + args: &'a PyTuple, + c: Option<&'a PyDict>, + kwargs: Option<&'a PyDict>, +) -> ( + i32, + &'a str, + &'a PyTuple, + Option<&'a PyDict>, + Option<&'a PyDict>, +) { + (a, b, args, c, kwargs) +} + #[pyfunction(args = "*", kwargs = "**")] -fn args_and_kwargs<'a>( +fn args_kwargs<'a>( args: &'a PyTuple, kwargs: Option<&'a PyDict>, ) -> (&'a PyTuple, Option<&'a PyDict>) { (args, kwargs) } -#[pyfunction(a, b = 2, args = "*", c = 4, kwargs = "**")] -fn mixed_args<'a>( - a: i32, - b: i32, - args: &'a PyTuple, - c: i32, - kwargs: Option<&'a PyDict>, -) -> (i32, i32, &'a PyTuple, i32, Option<&'a PyDict>) { - (a, b, args, c, kwargs) -} - -#[pyfunction] -fn no_args() {} - -#[pyfunction(b = 2, "*", c = 4)] -fn simple_args(a: i32, b: i32, c: i32) -> (i32, i32, i32) { - (a, b, c) -} - #[pymodule] fn _pyo3_benchmarks(_py: Python<'_>, m: &PyModule) -> PyResult<()> { - m.add_function(wrap_pyfunction!(args_and_kwargs, m)?)?; - m.add_function(wrap_pyfunction!(mixed_args, m)?)?; - m.add_function(wrap_pyfunction!(no_args, m)?)?; + m.add_function(wrap_pyfunction!(none, m)?)?; + m.add_function(wrap_pyfunction!(simple, m)?)?; m.add_function(wrap_pyfunction!(simple_args, m)?)?; + m.add_function(wrap_pyfunction!(simple_kwargs, m)?)?; + m.add_function(wrap_pyfunction!(simple_args_kwargs, m)?)?; + m.add_function(wrap_pyfunction!(args_kwargs, m)?)?; Ok(()) } diff --git a/examples/pyo3-benchmarks/tests/test_benchmarks.py b/examples/pyo3-benchmarks/tests/test_benchmarks.py index 0828b798..22d5b5f4 100644 --- a/examples/pyo3-benchmarks/tests/test_benchmarks.py +++ b/examples/pyo3-benchmarks/tests/test_benchmarks.py @@ -1,61 +1,91 @@ import pyo3_benchmarks -def test_args_and_kwargs(benchmark): - benchmark(pyo3_benchmarks.args_and_kwargs, 1, 2, 3, a=4, foo=10) - - -def args_and_kwargs_py(*args, **kwargs): - return (args, kwargs) - - -def test_args_and_kwargs_py(benchmark): - rust = pyo3_benchmarks.args_and_kwargs(1, 2, 3, bar=4, foo=10) - py = args_and_kwargs_py(1, 2, 3, bar=4, foo=10) - assert rust == py - benchmark(args_and_kwargs_py, 1, 2, 3, bar=4, foo=10) - - -def test_mixed_args(benchmark): - benchmark(pyo3_benchmarks.mixed_args, 1, 2, 3, bar=4, foo=10) - - -def mixed_args_py(a, b=2, *args, c=4, **kwargs): - return (a, b, args, c, kwargs) - - -def test_mixed_args_py(benchmark): - rust = pyo3_benchmarks.mixed_args(1, 2, 3, bar=4, foo=10) - py = mixed_args_py(1, 2, 3, bar=4, foo=10) - assert rust == py - benchmark(mixed_args_py, 1, 2, 3, bar=4, foo=10) - - -def test_no_args(benchmark): - benchmark(pyo3_benchmarks.no_args) - - -def no_args_py(): +def none_py(): return None -def test_no_args_py(benchmark): - rust = pyo3_benchmarks.no_args() - py = no_args_py() +def test_none_py(benchmark): + benchmark(none_py) + + +def test_none_rs(benchmark): + rust = pyo3_benchmarks.none() + py = none_py() assert rust == py - benchmark(no_args_py) + benchmark(pyo3_benchmarks.none) -def test_simple_args(benchmark): - benchmark(pyo3_benchmarks.simple_args, 1, 3, c=5) - - -def simple_args_py(a, b=2, *, c=4): +def simple_py(a, b="bar", *, c=None): return a, b, c -def test_simple_args_py(benchmark): - rust = pyo3_benchmarks.simple_args(1, 3, c=5) - py = simple_args_py(1, 3, c=5) +def test_simple_py(benchmark): + benchmark(simple_py, 1, "foo", c={1: 2}) + + +def test_simple_rs(benchmark): + rust = pyo3_benchmarks.simple(1, "foo", c={1: 2}) + py = simple_py(1, "foo", c={1: 2}) assert rust == py - benchmark(simple_args_py, 1, 3, c=5) + benchmark(pyo3_benchmarks.simple, 1, "foo", c={1: 2}) + + +def simple_args_py(a, b="bar", *args, c=None): + return a, b, args, c + + +def test_simple_args_py(benchmark): + benchmark(simple_args_py, 1, "foo", 4, 5, 6, c={1: 2}) + + +def test_simple_args_rs(benchmark): + rust = pyo3_benchmarks.simple_args(1, "foo", 4, 5, 6, c={1: 2}) + py = simple_args_py(1, "foo", 4, 5, 6, c={1: 2}) + assert rust == py + benchmark(pyo3_benchmarks.simple_args, 1, "foo", 4, 5, 6, c={1: 2}) + + +def simple_kwargs_py(a, b="bar", c=None, **kwargs): + return a, b, c, kwargs + + +def test_simple_kwargs_py(benchmark): + benchmark(simple_kwargs_py, 1, "foo", c={1: 2}, bar=4, foo=10) + + +def test_simple_kwargs_rs(benchmark): + rust = pyo3_benchmarks.simple_kwargs(1, "foo", c={1: 2}, bar=4, foo=10) + py = simple_kwargs_py(1, "foo", c={1: 2}, bar=4, foo=10) + assert rust == py + benchmark(pyo3_benchmarks.simple_kwargs, 1, "foo", c={1: 2}, bar=4, foo=10) + + +def simple_args_kwargs_py(a, b="bar", *args, c=None, **kwargs): + return (a, b, args, c, kwargs) + + +def test_simple_args_kwargs_py(benchmark): + benchmark(simple_args_kwargs_py, 1, "foo", "baz", bar=4, foo=10) + + +def test_simple_args_kwargs_rs(benchmark): + rust = pyo3_benchmarks.simple_args_kwargs(1, "foo", "baz", bar=4, foo=10) + py = simple_args_kwargs_py(1, "foo", "baz", bar=4, foo=10) + assert rust == py + benchmark(pyo3_benchmarks.simple_args_kwargs, 1, "foo", "baz", bar=4, foo=10) + + +def args_kwargs_py(*args, **kwargs): + return (args, kwargs) + + +def test_args_kwargs_py(benchmark): + benchmark(args_kwargs_py, 1, "foo", {1: 2}, bar=4, foo=10) + + +def test_args_kwargs_rs(benchmark): + rust = pyo3_benchmarks.args_kwargs(1, "foo", {1: 2}, bar=4, foo=10) + py = args_kwargs_py(1, "foo", {1: 2}, bar=4, foo=10) + assert rust == py + benchmark(pyo3_benchmarks.args_kwargs, 1, "foo", {1: 2}, a=4, foo=10) diff --git a/examples/pyo3-benchmarks/tox.ini b/examples/pyo3-benchmarks/tox.ini index e0d45bbc..bd2fba74 100644 --- a/examples/pyo3-benchmarks/tox.ini +++ b/examples/pyo3-benchmarks/tox.ini @@ -7,4 +7,4 @@ description = Run the unit tests under {basepython} deps = -rrequirements-dev.txt commands = python setup.py install - pytest {posargs} + pytest --benchmark-sort=name {posargs}