This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author rhettinger
Recipients lukasz.langa, petr.viktorin, pitrou, rhettinger, vstinner
Date 2020-07-03.21:40:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1593812406.28.0.0784680807835.issue39542@roundup.psfhosted.org>
In-reply-to
Content
PyTuple_Check() got slower across the board.  This is problematic because the principal use case for PyTuple_Check() is as a guard for various fast paths.

The direct cause of the degradation is that the inlining of PyType_Check() didn't go so well — commit 509dd90f4684e40af3105dd3e754fa4b9c1530c1. 

There are two issues.  First, we lost the fast path for an exact type match that was present in the 3.8 version of PyType_Check().  Second, functions like PyType_Check() cannot be fully inlined if they call other non-inlined functions like PyType_GetFlags().

The original unreviewed commit doesn't revert cleanly because subsequent changes were made.  Instead, I suggest:

* restore the short-cut for an exact type match, and
* convert PyType_GetFlags() to a macro or an inlined function

That would fix the performance regression while still treating type objects as opaque.

------- Incomplete inlines ----------------------------------------------
------- line 639 in object.h --------------------------------------------

static inline int
PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
    return ((PyType_GetFlags(type) & feature) != 0);
}
               ^---- Non-static function cannot be inlined

#define PyType_FastSubclass(type, flag) PyType_HasFeature(type, flag)

static inline int _PyType_Check(PyObject *op) {
    return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS);
}
#define PyType_Check(op) _PyType_Check(_PyObject_CAST(op))


------- Old Type Check Code ---------------------------------------------
------- line 646 in object.h --------------------------------------------

#define PyObject_TypeCheck(ob, tp) \
    (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp)))
                 ^--- Fast path for exact match is now gone


------- Non-static function cannot be inlined --------------------------
------- line 2339 in typeobject.c  -------------------------------------

unsigned long
PyType_GetFlags(PyTypeObject *type)
{
    return type->tp_flags;
}
History
Date User Action Args
2020-07-03 21:40:06rhettingersetrecipients: + rhettinger, pitrou, vstinner, petr.viktorin, lukasz.langa
2020-07-03 21:40:06rhettingersetmessageid: <1593812406.28.0.0784680807835.issue39542@roundup.psfhosted.org>
2020-07-03 21:40:06rhettingerlinkissue39542 messages
2020-07-03 21:40:06rhettingercreate