summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSergey B Kirpichev <skirpichev@gmail.com>2024-10-31 10:37:03 (GMT)
committerGitHub <noreply@github.com>2024-10-31 10:37:03 (GMT)
commit8c22eba877225ab29cd64672dcb97f09a5f7336f (patch)
treeee74e354c3f99cacf2e3a14d56dbc49e8a08d0a5 /Objects
parentd07dcce6935364cab807e0df931ed09b088ade69 (diff)
downloadcpython-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.h102
-rw-r--r--Objects/setobject.c56
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);