AK: Early return from empty hash table lookups to avoid hashing

When calling get() or find() on an empty HashTable or HashMap, we can
avoid hashing the sought-after key.
This commit is contained in:
Andreas Kling 2024-03-16 07:17:09 +01:00
parent c0e0cb86e1
commit 6724f840cd
Notes: sideshowbarker 2024-07-17 08:45:34 +09:00
2 changed files with 20 additions and 0 deletions

View file

@ -101,6 +101,8 @@ public:
[[nodiscard]] IteratorType end() { return m_table.end(); }
[[nodiscard]] IteratorType find(K const& key)
{
if (m_table.is_empty())
return m_table.end();
return m_table.find(KeyTraits::hash(key), [&](auto& entry) { return KeyTraits::equals(entry.key, key); });
}
template<typename TUnaryPredicate>
@ -113,6 +115,8 @@ public:
[[nodiscard]] ConstIteratorType end() const { return m_table.end(); }
[[nodiscard]] ConstIteratorType find(K const& key) const
{
if (m_table.is_empty())
return m_table.end();
return m_table.find(KeyTraits::hash(key), [&](auto& entry) { return KeyTraits::equals(entry.key, key); });
}
template<typename TUnaryPredicate>
@ -124,12 +128,16 @@ public:
template<Concepts::HashCompatible<K> Key>
requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] IteratorType find(Key const& key)
{
if (m_table.is_empty())
return m_table.end();
return m_table.find(Traits<Key>::hash(key), [&](auto& entry) { return Traits<K>::equals(entry.key, key); });
}
template<Concepts::HashCompatible<K> Key>
requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] ConstIteratorType find(Key const& key) const
{
if (m_table.is_empty())
return m_table.end();
return m_table.find(Traits<Key>::hash(key), [&](auto& entry) { return Traits<K>::equals(entry.key, key); });
}

View file

@ -378,6 +378,8 @@ public:
[[nodiscard]] Iterator find(T const& value)
{
if (is_empty())
return end();
return find(TraitsForT::hash(value), [&](auto& entry) { return TraitsForT::equals(entry, value); });
}
@ -389,6 +391,8 @@ public:
[[nodiscard]] ConstIterator find(T const& value) const
{
if (is_empty())
return end();
return find(TraitsForT::hash(value), [&](auto& entry) { return TraitsForT::equals(entry, value); });
}
// FIXME: Support for predicates, while guaranteeing that the predicate call
@ -396,24 +400,32 @@ public:
template<Concepts::HashCompatible<T> K>
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] Iterator find(K const& value)
{
if (is_empty())
return end();
return find(Traits<K>::hash(value), [&](auto& entry) { return Traits<T>::equals(entry, value); });
}
template<Concepts::HashCompatible<T> K, typename TUnaryPredicate>
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] Iterator find(K const& value, TUnaryPredicate predicate)
{
if (is_empty())
return end();
return find(Traits<K>::hash(value), move(predicate));
}
template<Concepts::HashCompatible<T> K>
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] ConstIterator find(K const& value) const
{
if (is_empty())
return end();
return find(Traits<K>::hash(value), [&](auto& entry) { return Traits<T>::equals(entry, value); });
}
template<Concepts::HashCompatible<T> K, typename TUnaryPredicate>
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] ConstIterator find(K const& value, TUnaryPredicate predicate) const
{
if (is_empty())
return end();
return find(Traits<K>::hash(value), move(predicate));
}