From 318d35a7bca6c4e54c75705245ee07277ac6e32c Mon Sep 17 00:00:00 2001 From: Kwasi Mensah Date: Fri, 8 Jul 2016 15:34:28 +0000 Subject: [PATCH] [libc++] Check hash before calling __hash_table key_eq function Summary: The current implementations of __hash_table::find used by std::unordered_set/unordered_map call key_eq on each key that lands in the same bucket as the key you're looking for. However, since equal objects mush hash to the same value, you can short-circuit the possibly expensive call to key_eq by checking the hashes first. Reviewers: EricWF Subscribers: kmensah, cfe-commits Differential Revision: http://reviews.llvm.org/D21510 llvm-svn: 274857 --- libcxx/include/__hash_table | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 414019aa1fa9..8b2565968cf8 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -2205,7 +2205,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) || __constrain_hash(__nd->__hash_, __bc) == __chash); __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __k)) + if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__nd, this); #else @@ -2235,7 +2235,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const || __constrain_hash(__nd->__hash_, __bc) == __chash); __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __k)) + if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return const_iterator(__nd, this); #else