Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wants to merge 1 commit into from

Conversation

vstinner
Copy link
Member

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

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:

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

@vstinner
Copy link
Member Author

@vstinner vstinner closed this May 22, 2024
@vstinner vstinner deleted the optim_object_str branch May 22, 2024 21:39
Sign up for free to 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