diff options
author | Guido van Rossum <guido@python.org> | 2002-08-09 02:14:34 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-08-09 02:14:34 (GMT) |
commit | 721f62e20059d36ae343993615aeecc1805b54fb (patch) | |
tree | 7cc0b6c758e9b9f631ba23bd7c7b36431dd42c80 /Objects | |
parent | c35491ee3a0f3999791de83e65ef94994058ac5e (diff) | |
download | cpython-721f62e20059d36ae343993615aeecc1805b54fb.zip cpython-721f62e20059d36ae343993615aeecc1805b54fb.tar.gz cpython-721f62e20059d36ae343993615aeecc1805b54fb.tar.bz2 |
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).
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f46734b..020cbf2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4081,6 +4081,28 @@ update_one_slot(PyTypeObject *type, slotdef *p) 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 { use_generic = 1; generic = p->function; |