Skip to content

Commit 9ca166c

Browse files
committed
Use _PyObject_GetMethodStackRef for slot_tp_new
1 parent 2f60b8f commit 9ca166c

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

Objects/typeobject.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10852,13 +10852,20 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1085210852
PyThreadState *tstate = _PyThreadState_GET();
1085310853
PyObject *func, *result;
1085410854

10855-
func = PyObject_GetAttr((PyObject *)type, &_Py_ID(__new__));
10856-
if (func == NULL) {
10855+
_PyCStackRef c_stackref;
10856+
_PyThreadState_PushCStackRef(tstate, &c_stackref);
10857+
int meth_found = _PyObject_GetMethodStackRef(tstate, (PyObject *)type, &_Py_ID(__new__), &c_stackref.ref);
10858+
10859+
if (PyStackRef_IsNull(c_stackref.ref)) {
10860+
_PyThreadState_PopCStackRef(tstate, &c_stackref);
1085710861
return NULL;
1085810862
}
10863+
func = PyStackRef_AsPyObjectBorrow(c_stackref.ref);
10864+
assert(func != NULL);
1085910865

1086010866
result = _PyObject_Call_Prepend(tstate, func, (PyObject *)type, args, kwds);
10861-
Py_DECREF(func);
10867+
//Py_DECREF(func);
10868+
_PyThreadState_PopCStackRef(tstate, &c_stackref);
1086210869
return result;
1086310870
}
1086410871

Tools/ftscalingbench/ftscalingbench.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import threading
2929
import time
3030
from operator import methodcaller
31+
from typing import NamedTuple
32+
from collections import namedtuple
3133

3234
# The iterations in individual benchmarks are scaled by this factor.
3335
WORK_SCALE = 100
@@ -38,11 +40,31 @@
3840
in_queues = []
3941
out_queues = []
4042

41-
4243
def register_benchmark(func):
4344
ALL_BENCHMARKS[func.__name__] = func
4445
return func
4546

47+
class Foo(NamedTuple):
48+
x: int
49+
50+
51+
Bar = namedtuple('Bar', ['x'])
52+
53+
@register_benchmark
54+
def typing_namedtuple():
55+
for i in range(1000 * WORK_SCALE):
56+
_ = Foo(x=1)
57+
58+
@register_benchmark
59+
def namedtuple():
60+
for i in range(1000 * WORK_SCALE):
61+
_ = Bar(x=1)
62+
63+
@register_benchmark
64+
def namedtuple():
65+
for i in range(1000 * WORK_SCALE):
66+
_ = Foo(x=1)
67+
4668
@register_benchmark
4769
def object_cfunction():
4870
accu = 0

0 commit comments

Comments
 (0)