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 <thiago.macieira@intel.com>
This commit is contained in:
Mårten Nordheim 2023-05-19 01:05:12 +02:00
parent c8e59d682c
commit 9afd4f6814

View File

@ -684,11 +684,16 @@ struct Data
}
template <typename K> Bucket findBucket(const K &key) const noexcept
{
size_t hash = QHashPrivate::calculateHash(key, seed);
return findBucketWithHash(key, hash);
}
template <typename K> Bucket findBucketWithHash(const K &key, size_t hash) const noexcept
{
static_assert(std::is_same_v<std::remove_cv_t<Key>, K> ||
QHashHeterogeneousSearch<std::remove_cv_t<Key>, 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 <typename K> InsertionResult findOrInsert(const K &key) noexcept
{
Bucket it(static_cast<Span *>(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();