diff options
author | Christian Tismer <tismer@stackless.com> | 2022-11-29 11:57:40 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-11-30 12:04:18 +0000 |
commit | 18ced2d4ef8bdcc0e240df4eccb62737c03a2483 (patch) | |
tree | 4139e218788aaff720e097173bc1900eec66ce02 | |
parent | 384a47c9d0b097a75ce6df4ba0cb81684cef1e5a (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
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit f391cd15394abf69581cc6cbe3663927f053342e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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); |