diff options
author | Sergey B Kirpichev <skirpichev@gmail.com> | 2024-10-31 10:37:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-31 10:37:03 (GMT) |
commit | 8c22eba877225ab29cd64672dcb97f09a5f7336f (patch) | |
tree | ee74e354c3f99cacf2e3a14d56dbc49e8a08d0a5 /Objects | |
parent | d07dcce6935364cab807e0df931ed09b088ade69 (diff) | |
download | cpython-8c22eba877225ab29cd64672dcb97f09a5f7336f.zip cpython-8c22eba877225ab29cd64672dcb97f09a5f7336f.tar.gz cpython-8c22eba877225ab29cd64672dcb97f09a5f7336f.tar.bz2 |
gh-90370: Argument Clinic: avoid temporary tuple creation for varargs (#126064)
Avoid temporary tuple creation when all arguments either positional-only
or vararg.
Objects/setobject.c and Modules/gcmodule.c adapted. This fixes slight
performance regression for set methods, introduced by gh-115112.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/clinic/setobject.c.h | 102 | ||||
-rw-r--r-- | Objects/setobject.c | 56 |
2 files changed, 65 insertions, 93 deletions
diff --git a/Objects/clinic/setobject.c.h b/Objects/clinic/setobject.c.h index 3853ce3..d6e381a 100644 --- a/Objects/clinic/setobject.c.h +++ b/Objects/clinic/setobject.c.h @@ -41,28 +41,22 @@ PyDoc_STRVAR(set_update__doc__, {"update", _PyCFunction_CAST(set_update), METH_FASTCALL, set_update__doc__}, static PyObject * -set_update_impl(PySetObject *so, PyObject *args); +set_update_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args); static PyObject * set_update(PySetObject *so, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("update", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = set_update_impl(so, __clinic_args); + __clinic_args = args + 0; + return_value = set_update_impl(so, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -148,28 +142,22 @@ PyDoc_STRVAR(set_union__doc__, {"union", _PyCFunction_CAST(set_union), METH_FASTCALL, set_union__doc__}, static PyObject * -set_union_impl(PySetObject *so, PyObject *args); +set_union_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args); static PyObject * set_union(PySetObject *so, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("union", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = set_union_impl(so, __clinic_args); + __clinic_args = args + 0; + return_value = set_union_impl(so, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -183,28 +171,23 @@ PyDoc_STRVAR(set_intersection_multi__doc__, {"intersection", _PyCFunction_CAST(set_intersection_multi), METH_FASTCALL, set_intersection_multi__doc__}, static PyObject * -set_intersection_multi_impl(PySetObject *so, PyObject *args); +set_intersection_multi_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args); static PyObject * set_intersection_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("intersection", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = set_intersection_multi_impl(so, __clinic_args); + __clinic_args = args + 0; + return_value = set_intersection_multi_impl(so, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -218,28 +201,23 @@ PyDoc_STRVAR(set_intersection_update_multi__doc__, {"intersection_update", _PyCFunction_CAST(set_intersection_update_multi), METH_FASTCALL, set_intersection_update_multi__doc__}, static PyObject * -set_intersection_update_multi_impl(PySetObject *so, PyObject *args); +set_intersection_update_multi_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args); static PyObject * set_intersection_update_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("intersection_update", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = set_intersection_update_multi_impl(so, __clinic_args); + __clinic_args = args + 0; + return_value = set_intersection_update_multi_impl(so, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -277,28 +255,23 @@ PyDoc_STRVAR(set_difference_update__doc__, {"difference_update", _PyCFunction_CAST(set_difference_update), METH_FASTCALL, set_difference_update__doc__}, static PyObject * -set_difference_update_impl(PySetObject *so, PyObject *args); +set_difference_update_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args); static PyObject * set_difference_update(PySetObject *so, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("difference_update", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = set_difference_update_impl(so, __clinic_args); + __clinic_args = args + 0; + return_value = set_difference_update_impl(so, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -312,28 +285,23 @@ PyDoc_STRVAR(set_difference_multi__doc__, {"difference", _PyCFunction_CAST(set_difference_multi), METH_FASTCALL, set_difference_multi__doc__}, static PyObject * -set_difference_multi_impl(PySetObject *so, PyObject *args); +set_difference_multi_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args); static PyObject * set_difference_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("difference", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = set_difference_multi_impl(so, __clinic_args); + __clinic_args = args + 0; + return_value = set_difference_multi_impl(so, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -568,4 +536,4 @@ set___sizeof__(PySetObject *so, PyObject *Py_UNUSED(ignored)) return return_value; } -/*[clinic end generated code: output=de4ee725bd29f758 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9d4b41191b2c602f input=a9049054013a1b77]*/ diff --git a/Objects/setobject.c b/Objects/setobject.c index 9f40e08..66d7fc7 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1060,13 +1060,13 @@ Update the set, adding elements from all others. [clinic start generated code]*/ static PyObject * -set_update_impl(PySetObject *so, PyObject *args) -/*[clinic end generated code: output=34f6371704974c8a input=df4fe486e38cd337]*/ +set_update_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args) +/*[clinic end generated code: output=050e2a21f8d7d16a input=df4fe486e38cd337]*/ { Py_ssize_t i; - for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { - PyObject *other = PyTuple_GET_ITEM(args, i); + for (i = 0; i < nargs; i++) { + PyObject *other = args[i]; if (set_update_internal(so, other)) return NULL; } @@ -1289,8 +1289,8 @@ Return a new set with elements from the set and all others. [clinic start generated code]*/ static PyObject * -set_union_impl(PySetObject *so, PyObject *args) -/*[clinic end generated code: output=2c83d05a446a1477 input=ddf088706e9577b2]*/ +set_union_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args) +/*[clinic end generated code: output=f68ec24d5c19d404 input=ddf088706e9577b2]*/ { PySetObject *result; PyObject *other; @@ -1300,8 +1300,8 @@ set_union_impl(PySetObject *so, PyObject *args) if (result == NULL) return NULL; - for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { - other = PyTuple_GET_ITEM(args, i); + for (i = 0; i < nargs; i++) { + other = args[i]; if ((PyObject *)so == other) continue; if (set_update_local(result, other)) { @@ -1440,18 +1440,19 @@ Return a new set with elements common to the set and all others. [clinic start generated code]*/ static PyObject * -set_intersection_multi_impl(PySetObject *so, PyObject *args) -/*[clinic end generated code: output=2406ef3387adbe2f input=0d9f3805ccbba6a4]*/ +set_intersection_multi_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=ef0756ddb5f2dee9 input=0d9f3805ccbba6a4]*/ { Py_ssize_t i; - if (PyTuple_GET_SIZE(args) == 0) { + if (nargs == 0) { return set_copy(so, NULL); } PyObject *result = Py_NewRef(so); - for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { - PyObject *other = PyTuple_GET_ITEM(args, i); + for (i = 0; i < nargs; i++) { + PyObject *other = args[i]; PyObject *newresult; Py_BEGIN_CRITICAL_SECTION2(result, other); newresult = set_intersection((PySetObject *)result, other); @@ -1487,12 +1488,13 @@ Update the set, keeping only elements found in it and all others. [clinic start generated code]*/ static PyObject * -set_intersection_update_multi_impl(PySetObject *so, PyObject *args) -/*[clinic end generated code: output=251c1f729063609d input=223c1e086aa669a9]*/ +set_intersection_update_multi_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=808d7ad1935b1dfe input=223c1e086aa669a9]*/ { PyObject *tmp; - tmp = set_intersection_multi_impl(so, args); + tmp = set_intersection_multi_impl(so, nargs, args); if (tmp == NULL) return NULL; Py_BEGIN_CRITICAL_SECTION(so); @@ -1676,13 +1678,14 @@ Update the set, removing elements found in others. [clinic start generated code]*/ static PyObject * -set_difference_update_impl(PySetObject *so, PyObject *args) -/*[clinic end generated code: output=28685b2fc63e41c4 input=024e6baa6fbcbb3d]*/ +set_difference_update_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=55f850c27748d312 input=024e6baa6fbcbb3d]*/ { Py_ssize_t i; - for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { - PyObject *other = PyTuple_GET_ITEM(args, i); + for (i = 0; i < nargs; i++) { + PyObject *other = args[i]; int rv; Py_BEGIN_CRITICAL_SECTION2(so, other); rv = set_difference_update_internal(so, other); @@ -1793,25 +1796,26 @@ Return a new set with elements in the set that are not in the others. [clinic start generated code]*/ static PyObject * -set_difference_multi_impl(PySetObject *so, PyObject *args) -/*[clinic end generated code: output=3130c3bb3cac873d input=ba78ea5f099e58df]*/ +set_difference_multi_impl(PySetObject *so, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=8150d008c00523f3 input=ba78ea5f099e58df]*/ { Py_ssize_t i; PyObject *result, *other; - if (PyTuple_GET_SIZE(args) == 0) { + if (nargs == 0) { return set_copy(so, NULL); } - other = PyTuple_GET_ITEM(args, 0); + other = args[0]; Py_BEGIN_CRITICAL_SECTION2(so, other); result = set_difference(so, other); Py_END_CRITICAL_SECTION2(); if (result == NULL) return NULL; - for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) { - other = PyTuple_GET_ITEM(args, i); + for (i = 1; i < nargs; i++) { + other = args[i]; int rv; Py_BEGIN_CRITICAL_SECTION(other); rv = set_difference_update_internal((PySetObject *)result, other); |