Skip to content

Conversation

@vstinner
Copy link
Member

@vstinnervstinner commented May 22, 2024

Add fast paths for str, int and float object types.

Benchmark on %S and %R formats:

+----------------+--------+----------------------+ | Benchmark | ref | change | +================+========+======================+ | str() | 654 ns | 556 ns: 1.18x faster | +----------------+--------+----------------------+ | repr() | 722 ns | 627 ns: 1.15x faster | +----------------+--------+----------------------+ | Geometric mean | (ref) | 1.16x faster | +----------------+--------+----------------------+ 

Add fast paths for str, int and float object types. Benchmark on %S and %R formats: +----------------+--------+----------------------+ | Benchmark | ref | change | +================+========+======================+ | str() | 654 ns | 556 ns: 1.18x faster | +----------------+--------+----------------------+ | repr() | 722 ns | 627 ns: 1.15x faster | +----------------+--------+----------------------+ | Geometric mean | (ref) | 1.16x faster | +----------------+--------+----------------------+
@vstinner
Copy link
MemberAuthor

Benchmark:

diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f99ebf0dde..53d2a8e5f7 100644 --- a/Modules/_testcapimodule.c+++ b/Modules/_testcapimodule.c@@ -3312,6 +3312,46 @@ function_set_warning(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) Py_RETURN_NONE} +static PyObject *+bench_str(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))+{+ PyObject *abc = PyUnicode_FromString("abc");+ assert(abc != NULL);+ PyObject *intobj = PyLong_FromLong(123);+ assert(intobj != NULL);+ PyObject *floatobj = PyFloat_FromDouble(1.0);+ assert(floatobj != NULL);++ PyObject *res = PyUnicode_FromFormat(+ "str: %S, int: %S, float: %S",+ abc, intobj, floatobj);++ Py_DECREF(abc);+ Py_DECREF(intobj);+ Py_DECREF(floatobj);+ return res;+}++static PyObject *+bench_repr(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))+{+ PyObject *abc = PyUnicode_FromString("abc");+ assert(abc != NULL);+ PyObject *intobj = PyLong_FromLong(123);+ assert(intobj != NULL);+ PyObject *floatobj = PyFloat_FromDouble(1.0);+ assert(floatobj != NULL);++ PyObject *res = PyUnicode_FromFormat(+ "str: %R, int: %R, float: %R",+ abc, intobj, floatobj);++ Py_DECREF(abc);+ Py_DECREF(intobj);+ Py_DECREF(floatobj);+ return res;+}+ static PyMethodDef TestMethods[] ={{"set_errno", set_errno, METH_VARARGS},{"test_config", test_config, METH_NOARGS}, @@ -3454,6 +3494,8 @@ static PyMethodDef TestMethods[] ={{"check_pyimport_addmodule", check_pyimport_addmodule, METH_VARARGS},{"test_weakref_capi", test_weakref_capi, METH_NOARGS},{"function_set_warning", function_set_warning, METH_NOARGS}, +{"bench_str", bench_str, METH_NOARGS},+{"bench_repr", bench_repr, METH_NOARGS},{NULL, NULL} /* sentinel */ }; 

Script:

importpyperfimport_testcapirunner=pyperf.Runner() runner.bench_func('str()', _testcapi.bench_str) runner.bench_func('repr()', _testcapi.bench_repr)

@vstinner
Copy link
MemberAuthor

@vstinnervstinner deleted the optim_object_str branch May 22, 2024 21:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@vstinner