-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
gh-139888: Add PyTupleWriter C API (stack flavor) #140129
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
Conversation
* Add _PyTuple_NewNoTrack() and _PyTuple_ResizeNoTrack() helper functions. * Modify PySequence_Tuple() to use PyTupleWriter API. * Soft deprecate _PyTuple_Resize().
40be397 to
e5a4e4e
Compare
|
Benchmark based on my previous benchmark. Compare
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 4e73be20e1b..2a1d0b85a23 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2562,6 +2562,74 @@ toggle_reftrace_printer(PyObject *ob, PyObject *arg)
Py_RETURN_NONE;
}
+static PyObject *
+bench_tuple(PyObject *ob, PyObject *args)
+{
+ Py_ssize_t size, loops;
+ if (!PyArg_ParseTuple(args, "nn", &size, &loops)) {
+ return NULL;
+ }
+
+ PyTime_t t1, t2;
+ PyTime_PerfCounterRaw(&t1);
+ for (Py_ssize_t i=0; i < loops; i++) {
+ PyObject *tuple = PyTuple_New(size);
+ if (tuple == NULL) {
+ return NULL;
+ }
+
+ for (int i=0; i < size; i++) {
+ PyObject *item = PyLong_FromLong(i);
+ if (item == NULL) {
+ Py_DECREF(tuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(tuple, i, item);
+ }
+
+ Py_DECREF(tuple);
+ }
+ PyTime_PerfCounterRaw(&t2);
+ return PyFloat_FromDouble(PyTime_AsSecondsDouble(t2 - t1));
+}
+
+static PyObject *
+bench_writer(PyObject *ob, PyObject *args)
+{
+ Py_ssize_t size, loops;
+ if (!PyArg_ParseTuple(args, "nn", &size, &loops)) {
+ return NULL;
+ }
+
+ PyTime_t t1, t2;
+ PyTime_PerfCounterRaw(&t1);
+ for (Py_ssize_t i=0; i < loops; i++) {
+ PyTupleWriter writer;
+ if (PyTupleWriter_Init(&writer, size) < 0) {
+ return NULL;
+ }
+
+ for (int i=0; i < size; i++) {
+ PyObject *item = PyLong_FromLong(i);
+ if (item == NULL) {
+ return NULL;
+ }
+ if (PyTupleWriter_AddSteal(&writer, item) < 0) {
+ PyTupleWriter_Discard(&writer);
+ return NULL;
+ }
+ }
+
+ PyObject *tuple = PyTupleWriter_Finish(&writer);
+ if (tuple == NULL) {
+ return NULL;
+ }
+ Py_DECREF(tuple);
+ }
+ PyTime_PerfCounterRaw(&t2);
+ return PyFloat_FromDouble(PyTime_AsSecondsDouble(t2 - t1));
+}
+
static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
@@ -2656,6 +2724,8 @@ static PyMethodDef TestMethods[] = {
{"test_atexit", test_atexit, METH_NOARGS},
{"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL},
{"toggle_reftrace_printer", toggle_reftrace_printer, METH_O},
+ {"bench_tuple", bench_tuple, METH_VARARGS},
+ {"bench_writer", bench_writer, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
|
Co-authored-by: Maurycy Pawłowski-Wieroński <[email protected]>
|
I wrote this API to get rid of I failed to convince other core developers that this I prefer to give up on |
PyTupleWriterAPI #139888📚 Documentation preview 📚: https://cpython-previews--140129.org.readthedocs.build/