Skip to content

gh-119396: Optimize %S format of PyUnicode_FromFormat() - #119412

Closed
vstinner wants to merge 1 commit into
python:mainfrom
vstinner:optim_object_str
Closed

gh-119396: Optimize %S format of PyUnicode_FromFormat()#119412
vstinner wants to merge 1 commit into
python:mainfrom
vstinner:optim_object_str

Conversation

@vstinner

@vstinnervstinner commented May 22, 2024

Copy link
Copy Markdown
Member

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
Copy Markdown
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
Copy Markdown
MemberAuthor

@vstinner
vstinner 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