mirror of
https://github.com/python/cpython.git
synced 2025-11-03 11:23:31 +00:00
Major speedup for new-style class creation. Turns out there was some
trampolining going on with the tp_new descriptor, where the inherited PyType_GenericNew was overwritten with the much slower slot_tp_new which would end up calling tp_new_wrapper which would eventually call PyType_GenericNew. Add a special case for this to update_one_slot(). XXX Hope there isn't a loophole in this. I'll buy the first person to point out a bug in the reasoning a beer. Backport candidate (but I won't do it).
This commit is contained in:
parent
c35491ee3a
commit
721f62e200
1 changed files with 22 additions and 0 deletions
|
|
@ -4081,6 +4081,28 @@ update_one_slot(PyTypeObject *type, slotdef *p)
|
||||||
use_generic = 1;
|
use_generic = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (descr->ob_type == &PyCFunction_Type &&
|
||||||
|
PyCFunction_GET_FUNCTION(descr) ==
|
||||||
|
(PyCFunction)tp_new_wrapper &&
|
||||||
|
strcmp(p->name, "__new__") == 0)
|
||||||
|
{
|
||||||
|
/* The __new__ wrapper is not a wrapper descriptor,
|
||||||
|
so must be special-cased differently.
|
||||||
|
If we don't do this, creating an instance will
|
||||||
|
always use slot_tp_new which will look up
|
||||||
|
__new__ in the MRO which will call tp_new_wrapper
|
||||||
|
which will look through the base classes looking
|
||||||
|
for a static base and call its tp_new (usually
|
||||||
|
PyType_GenericNew), after performing various
|
||||||
|
sanity checks and constructing a new argument
|
||||||
|
list. Cut all that nonsense short -- this speeds
|
||||||
|
up instance creation tremendously. */
|
||||||
|
specific = type->tp_new;
|
||||||
|
/* XXX I'm not 100% sure that there isn't a hole
|
||||||
|
in this reasoning that requires additional
|
||||||
|
sanity checks. I'll buy the first person to
|
||||||
|
point out a bug in this reasoning a beer. */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
use_generic = 1;
|
use_generic = 1;
|
||||||
generic = p->function;
|
generic = p->function;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue