From 02aa2362560f1b458b9eaa2f8ba3f27362d0f3ea Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 3 Aug 2021 17:19:23 +0200 Subject: [PATCH] QMetaTypeFunctionRegistry: avoid double-lookup in insertIfNotContains() Because there's no insertIfNotContains()-like functionality in QHash (unlike std::unordered_map, where insert() doesn't overwrite an existing entry), the code first called contains(k) and then insert(k, ~~~), causing two lookups in the case where the insertion actually happens. Fix by using the pattern QDuplicateTracker's QSet fall-back uses, too: recording the size before and after the call to the indexing operator and using a size increase as the criterion that an insertion should happen. This reduces the number of lookups to one, at the cost of a mapped_type default construction (which, given mapped_type is std::function, should be cheap). Change-Id: I24b31107b3e26f2eea2edce7b46f8cb5e7cb35bf Reviewed-by: Fabian Kosmale --- src/corelib/kernel/qmetatype.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 65745bf06a..41b991580f 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1560,9 +1560,11 @@ public: bool insertIfNotContains(Key k, const T &f) { const QWriteLocker locker(&lock); - if (map.contains(k)) + const qsizetype oldSize = map.size(); + auto &e = map[k]; + if (map.size() == oldSize) // already present return false; - map.insert(k, f); + e = f; return true; }