aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2022-11-29 11:57:40 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-11-30 12:04:18 +0000
commit18ced2d4ef8bdcc0e240df4eccb62737c03a2483 (patch)
tree4139e218788aaff720e097173bc1900eec66ce02
parent384a47c9d0b097a75ce6df4ba0cb81684cef1e5a (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.cpp23
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);