summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.cpp
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2021-07-02 08:32:09 +0200
committerMarc Mutz <marc.mutz@kdab.com>2021-07-13 16:57:31 +0200
commit2b50c8bec086ae975ac5152e08f6b3dcf76306a0 (patch)
tree656fded2be7e3e7d8d7d7c9336da8e1bad0d7ac7 /src/corelib/kernel/qobject.cpp
parent1edb51a315c4ab307878d6620d8d7484cc080d09 (diff)
QObject: optimize the common case of findChildren(QString())
Outside tests, all in-tree callers of QObject::findChildren() pass no name to match, and in my experience that is also true for the vast majority of out-of-tree users. Avoid the temporary QString creation in the caller and the repeated QString::isNull() checks in the implementation by overloading findChildren() without a name argument and checking for name.isNull() only once, forking off into separate helper functions. Adjust in-tree callers that used an explicit `QString()` argument in order to pass options, which goes to show that `name` should never have been the first argument of findChilden() in the first place, even though I appreciate the symmetry with findChild() (the use-cases of which, however, are radically different). Change a `findChildren().size() == 0` call found while scanning for findChildren() calls to `!findChild()` as a drive-by. Modernize loops in the various qt_qFindChild{,ren}_helper() overloads to match how the new code looks. [ChangeLog][QtCore][QObject] Added findChildren() overload taking no name (thus optimizing this common case). Change-Id: Ifc56e5438023d079b40c67f11ae274a3e128ad5e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r--src/corelib/kernel/qobject.cpp74
1 files changed, 51 insertions, 23 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 8eb2af0c61..d524fd4305 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1947,7 +1947,8 @@ void QObject::killTimer(int id)
Returns all children of this object with the given \a name that can be
cast to type T, or an empty list if there are no such objects.
- Omitting the \a name argument causes all object names to be matched.
+ A null \a name argument causes all objects to be matched, an empty one
+ only those whose objectName is empty.
The search is performed recursively, unless \a options specifies the
option FindDirectChildrenOnly.
@@ -1968,6 +1969,19 @@ void QObject::killTimer(int id)
*/
/*!
+ \fn template<typename T> QList<T> QObject::findChildren(Qt::FindChildOptions options) const
+ \overload
+ \since 6.3
+
+ Returns all children of this object that can be cast to type T, or
+ an empty list if there are no such objects.
+ The search is performed recursively, unless \a options specifies the
+ option FindDirectChildrenOnly.
+
+ \sa findChild()
+*/
+
+/*!
\fn QList<T> QObject::findChildren(const QRegularExpression &re, Qt::FindChildOptions options) const
\overload findChildren()
@@ -2012,24 +2026,46 @@ void QObject::killTimer(int id)
\sa QObject::findChildren()
*/
+static void qt_qFindChildren_with_name(const QObject *parent, const QString &name,
+ const QMetaObject &mo, QList<void *> *list,
+ Qt::FindChildOptions options)
+{
+ Q_ASSERT(parent);
+ Q_ASSERT(list);
+ Q_ASSERT(!name.isNull());
+ for (QObject *obj : parent->children()) {
+ if (mo.cast(obj) && obj->objectName() == name)
+ list->append(obj);
+ if (options & Qt::FindChildrenRecursively)
+ qt_qFindChildren_with_name(obj, name, mo, list, options);
+ }
+}
+
/*!
\internal
*/
void qt_qFindChildren_helper(const QObject *parent, const QString &name,
const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
{
+ if (name.isNull())
+ return qt_qFindChildren_helper(parent, mo, list, options);
+ else
+ return qt_qFindChildren_with_name(parent, name, mo, list, options);
+}
+
+/*!
+ \internal
+*/
+void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo,
+ QList<void*> *list, Qt::FindChildOptions options)
+{
Q_ASSERT(parent);
Q_ASSERT(list);
- const QObjectList &children = parent->children();
- QObject *obj;
- for (int i = 0; i < children.size(); ++i) {
- obj = children.at(i);
- if (mo.cast(obj)) {
- if (name.isNull() || obj->objectName() == name)
- list->append(obj);
- }
+ for (QObject *obj : parent->children()) {
+ if (mo.cast(obj))
+ list->append(obj);
if (options & Qt::FindChildrenRecursively)
- qt_qFindChildren_helper(obj, name, mo, list, options);
+ qt_qFindChildren_helper(obj, mo, list, options);
}
}
@@ -2042,10 +2078,7 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re
{
Q_ASSERT(parent);
Q_ASSERT(list);
- const QObjectList &children = parent->children();
- QObject *obj;
- for (int i = 0; i < children.size(); ++i) {
- obj = children.at(i);
+ for (QObject *obj : parent->children()) {
if (mo.cast(obj)) {
QRegularExpressionMatch m = re.match(obj->objectName());
if (m.hasMatch())
@@ -2063,18 +2096,13 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
{
Q_ASSERT(parent);
- const QObjectList &children = parent->children();
- QObject *obj;
- int i;
- for (i = 0; i < children.size(); ++i) {
- obj = children.at(i);
+ for (QObject *obj : parent->children()) {
if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
return obj;
}
if (options & Qt::FindChildrenRecursively) {
- for (i = 0; i < children.size(); ++i) {
- obj = qt_qFindChild_helper(children.at(i), name, mo, options);
- if (obj)
+ for (QObject *child : parent->children()) {
+ if (QObject *obj = qt_qFindChild_helper(child, name, mo, options))
return obj;
}
}
@@ -3593,7 +3621,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
const QMetaObject *mo = o->metaObject();
Q_ASSERT(mo);
const QObjectList list = // list of all objects to look for matching signals including...
- o->findChildren<QObject *>(QString()) // all children of 'o'...
+ o->findChildren<QObject *>() // all children of 'o'...
<< o; // and the object 'o' itself
// for each method/slot of o ...