diff options
author | Christian Tismer <[email protected]> | 2022-11-29 11:57:40 +0100 |
---|---|---|
committer | Christian Tismer <[email protected]> | 2022-11-30 10:53:08 +0100 |
commit | f391cd15394abf69581cc6cbe3663927f053342e (patch) | |
tree | b71b915730621d68b7635e7137d58f3b38c04027 /sources/pyside6/libpyside/feature_select.cpp | |
parent | 0d03c6ce7e7320f9b30e29782884f453c9eff2f6 (diff) |
__feature__: Add some simple but very effective caching
The caching problem has been studied a while and multiple
schemes have been considered which are not really cheap,
partially since a lot of extra knowledge would need to be
recorded.
While testing, it turned out that very often the same type
gets accessed multiple times, which allows for a very
efficient cache without the chance of errors:
Simply save multiple selection with the same type and select id.
[ChangeLog][PySide6] A new efficient optimization was implemented
for __feature__ switching.
Task-number: PYSIDE-2029
Change-Id: I76d4dc81f7a038ff47af13f0a77981844764f3a1
Pick-to: 6.4
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Friedemann Kleint <[email protected]>
Diffstat (limited to 'sources/pyside6/libpyside/feature_select.cpp')
-rw-r--r-- | sources/pyside6/libpyside/feature_select.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp index 695a0e61e..db28583c6 100644 --- a/sources/pyside6/libpyside/feature_select.cpp +++ b/sources/pyside6/libpyside/feature_select.cpp @@ -266,7 +266,7 @@ static bool createNewFeatureSet(PyTypeObject *type, PyObject *select_id) return true; } -static inline bool SelectFeatureSetSubtype(PyTypeObject *type, PyObject *select_id) +static inline void SelectFeatureSetSubtype(PyTypeObject *type, PyObject *select_id) { /* * This is the selector for one sublass. We need to call this for @@ -277,17 +277,16 @@ static inline bool SelectFeatureSetSubtype(PyTypeObject *type, PyObject *select_ // The dict type will be replaced after the first call. if (!replaceClassDict(type)) { Py_FatalError("failed to replace class dict!"); - return false; + return; } } if (!moveToFeatureSet(type, select_id)) { if (!createNewFeatureSet(type, select_id)) { Py_FatalError("failed to create a new feature set!"); - return false; + return; } } - return true; -} + } static inline void SelectFeatureSet(PyTypeObject *type) { @@ -307,17 +306,23 @@ static inline void SelectFeatureSet(PyTypeObject *type) } } - PyObject *select_id = getFeatureSelectId(); // borrowed + PyObject *select_id = getFeatureSelectId(); // borrowed + static PyObject *last_select_id{}; + static PyTypeObject *last_type{}; + + // PYSIDE-2029: Implement a very simple but effective cache that cannot fail. + if (type == last_type && select_id == last_select_id) + return; + last_type = type; + last_select_id = select_id; - // PYSIDE-2029: We are no longer caching extremely, but switching safe. PyObject *mro = type->tp_mro; Py_ssize_t idx, n = PyTuple_GET_SIZE(mro); // We leave 'Shiboken.Object' and 'object' alone, therefore "n - 2". for (idx = 0; idx < n - 2; idx++) { auto *sub_type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx)); // When any subtype is already resolved (false), we can stop. - if (!SelectFeatureSetSubtype(sub_type, select_id)) - break; + SelectFeatureSetSubtype(sub_type, select_id); } // PYSIDE-1436: Clear all caches for the type and subtypes. PyType_Modified(type); |