From 9afd4f68147ba3d11e456ab3d810b0a359a7ecc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 19 May 2023 01:05:12 +0200 Subject: [PATCH] QHash: reduce how many times we calculate hash by passing it around Result in some smaller speedups, because we now compute the hash once per insertion operation, and pass it around, instead of computing it once in every function where we need it. Though it's minimal, on my machine it executes around 1% less instructions per iteration. Change-Id: Ib84696cac56c379c37853dd4f0bc6ab4f5e440ad Reviewed-by: Thiago Macieira --- src/corelib/tools/qhash.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 6ef39ac5188..478e9e78ce0 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -684,11 +684,16 @@ struct Data } template Bucket findBucket(const K &key) const noexcept + { + size_t hash = QHashPrivate::calculateHash(key, seed); + return findBucketWithHash(key, hash); + } + + template Bucket findBucketWithHash(const K &key, size_t hash) const noexcept { static_assert(std::is_same_v, K> || QHashHeterogeneousSearch, K>::value); Q_ASSERT(numBuckets > 0); - size_t hash = QHashPrivate::calculateHash(key, seed); Bucket bucket(this, GrowthPolicy::bucketForHash(numBuckets, hash)); // loop over the buckets until we find the entry we search for // or an empty slot, in which case we know the entry doesn't exist @@ -722,14 +727,15 @@ struct Data template InsertionResult findOrInsert(const K &key) noexcept { Bucket it(static_cast(nullptr), 0); + size_t hash = QHashPrivate::calculateHash(key, seed); if (numBuckets > 0) { - it = findBucket(key); + it = findBucketWithHash(key, hash); if (!it.isUnused()) return { it.toIterator(this), true }; } if (shouldGrow()) { rehash(size + 1); - it = findBucket(key); // need to get a new iterator after rehashing + it = findBucketWithHash(key, hash); // need to get a new iterator after rehashing } Q_ASSERT(it.span != nullptr); Q_ASSERT(it.isUnused()); @@ -1436,7 +1442,8 @@ private: detach(); QHash detachGuard; - typename Data::Bucket bucket = d->findBucket(key); + size_t hash = QHashPrivate::calculateHash(key, d->seed); + typename Data::Bucket bucket = d->findBucketWithHash(key, hash); const bool shouldInsert = bucket.isUnused(); // Even if we don't insert we may have to detach because we are @@ -1448,7 +1455,7 @@ private: // Must detach from detachGuard d = resized ? Data::detached(d, d->size + 1) : Data::detached(d); - bucket = resized ? d->findBucket(key) : typename Data::Bucket(d, bucketIndex); + bucket = resized ? d->findBucketWithHash(key, hash) : typename Data::Bucket(d, bucketIndex); } if (shouldInsert) { Node *n = bucket.insert();