Skip to content

Commit e27916b

Browse files
authored
bpo-37207: Use PEP 590 vectorcall to speed up dict() (GH-19280)
1 parent 224e1c3 commit e27916b

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speed up calls to ``dict()`` by using the :pep:`590` ``vectorcall`` calling
2+
convention.

Objects/dictobject.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,6 +3342,38 @@ dict_init(PyObject *self, PyObject *args, PyObject *kwds)
33423342
return dict_update_common(self, args, kwds, "dict");
33433343
}
33443344

3345+
static PyObject *
3346+
dict_vectorcall(PyObject *type, PyObject * const*args,
3347+
size_t nargsf, PyObject *kwnames)
3348+
{
3349+
assert(PyType_Check(type));
3350+
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
3351+
if (!_PyArg_CheckPositional("dict", nargs, 0, 1)) {
3352+
return NULL;
3353+
}
3354+
3355+
PyObject *self = dict_new((PyTypeObject *)type, NULL, NULL);
3356+
if (self == NULL) {
3357+
return NULL;
3358+
}
3359+
if (nargs == 1) {
3360+
if (dict_update_arg(self, args[0]) < 0) {
3361+
Py_DECREF(self);
3362+
return NULL;
3363+
}
3364+
args++;
3365+
}
3366+
if (kwnames != NULL) {
3367+
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) {
3368+
if (PyDict_SetItem(self, PyTuple_GET_ITEM(kwnames, i), args[i]) < 0) {
3369+
Py_DECREF(self);
3370+
return NULL;
3371+
}
3372+
}
3373+
}
3374+
return self;
3375+
}
3376+
33453377
static PyObject *
33463378
dict_iter(PyDictObject *dict)
33473379
{
@@ -3400,6 +3432,7 @@ PyTypeObject PyDict_Type = {
34003432
PyType_GenericAlloc, /* tp_alloc */
34013433
dict_new, /* tp_new */
34023434
PyObject_GC_Del, /* tp_free */
3435+
.tp_vectorcall = dict_vectorcall,
34033436
};
34043437

34053438
PyObject *

0 commit comments

Comments
 (0)