From 6afc7cf1054f8f7602fa036d208af728aaf3c446 Mon Sep 17 00:00:00 2001 From: Davi Reis Date: Sat, 21 Apr 2012 21:48:32 +0200 Subject: [PATCH] Fastest true incarnation so far. Not much faster than unordered_map. --- cxxmph/bm_map.cc | 7 ++++--- cxxmph/mph_index.h | 14 +++++++------- cxxmph/mph_map.h | 21 ++++++++++++++++----- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/cxxmph/bm_map.cc b/cxxmph/bm_map.cc index 039b5d6..0f8dace 100644 --- a/cxxmph/bm_map.cc +++ b/cxxmph/bm_map.cc @@ -41,11 +41,12 @@ class BM_SearchUrls : public SearchUrlsBenchmark { : SearchUrlsBenchmark(urls_file, nsearches, miss_ratio) { } virtual ~BM_SearchUrls() {} virtual void Run() { + uint32_t total = 1; for (auto it = random_.begin(); it != random_.end(); ++it) { - myfind(mymap_, *it); - assert(it->ends_with(".force_miss") ^ v != NULL); - assert(!v || *v == *it); + auto v = myfind(mymap_, *it); + if (v) total += v->length(); } + fprintf(stderr, "Total: %u\n", total); } protected: virtual bool SetUp() { diff --git a/cxxmph/mph_index.h b/cxxmph/mph_index.h index 1f6ace1..84b7258 100644 --- a/cxxmph/mph_index.h +++ b/cxxmph/mph_index.h @@ -124,7 +124,7 @@ bool MPHIndex::Reset( if ((r_ % 2) == 0) r_ += 1; // This can be used to speed mods, but increases occupation too much. // Needs to try http://gmplib.org/manual/Integer-Exponentiation.html instead - // r_ = nextpoweroftwo(r_); + r_ = nextpoweroftwo(r_); nest_displacement_[0] = 0; nest_displacement_[1] = r_; nest_displacement_[2] = (r_ << 1); @@ -177,12 +177,12 @@ template uint32_t MPHIndex::perfect_hash(const Key& key) const { if (!g_.size()) return 0; h128 h = SeededHashFcn().hash128(key, hash_seed_[0]); - h[0] = (h[0] % r_) + nest_displacement_[0]; - h[1] = (h[1] % r_) + nest_displacement_[1]; - h[2] = (h[2] % r_) + nest_displacement_[2]; - // h[0] = (h[0] & (r_-1)) + nest_displacement_[0]; - // h[1] = (h[1] & (r_-1)) + nest_displacement_[1]; - // h[2] = (h[2] & (r_-1)) + nest_displacement_[2]; + // h[0] = (h[0] % r_) + nest_displacement_[0]; + // h[1] = (h[1] % r_) + nest_displacement_[1]; + // h[2] = (h[2] % r_) + nest_displacement_[2]; + h[0] = (h[0] & (r_-1)) + nest_displacement_[0]; + h[1] = (h[1] & (r_-1)) + nest_displacement_[1]; + h[2] = (h[2] & (r_-1)) + nest_displacement_[2]; assert((h[0]) < g_.size()); assert((h[1]) < g_.size()); assert((h[2]) < g_.size()); diff --git a/cxxmph/mph_map.h b/cxxmph/mph_map.h index 4d0276f..63095c5 100644 --- a/cxxmph/mph_map.h +++ b/cxxmph/mph_map.h @@ -79,6 +79,7 @@ class mph_map { inline const_iterator find(const key_type& k) const; typedef int32_t my_int32_t; // help macros inline int32_t index(const key_type& k) const; + inline int32_t index2(const key_type& k) const; data_type& operator[](const key_type &k); const data_type& operator[](const key_type &k) const; @@ -197,7 +198,7 @@ MPH_MAP_METHOD_DECL(void_type, erase)(const key_type& k) { } MPH_MAP_INLINE_METHOD_DECL(const_iterator, find)(const key_type& k) const { - auto idx = index(k); + auto idx = index2(k); typename vector::const_iterator vit = values_.begin() + idx; if (idx == -1 || vit->first != k) return end(); return make_solid(&values_, &present_, vit);; @@ -210,17 +211,27 @@ MPH_MAP_INLINE_METHOD_DECL(iterator, find)(const key_type& k) { return make_solid(&values_, &present_, vit);; } -MPH_MAP_INLINE_METHOD_DECL(my_int32_t, index)(const key_type& k) const { - if (__builtin_expect(!slack_.empty(), 0)) { - auto sit = slack_.find(hasher128_.hash128(k, 0)); - if (sit != slack_.end()) return sit->second; +MPH_MAP_INLINE_METHOD_DECL(my_int32_t, index2)(const key_type& k) const { + if (__builtin_expect(index_.perfect_hash_size(), 1)) { + auto perfect_hash = index_.perfect_hash(k); + return perfect_hash; } + return -1; +} + + + +MPH_MAP_INLINE_METHOD_DECL(my_int32_t, index)(const key_type& k) const { if (__builtin_expect(index_.perfect_hash_size(), 1)) { auto perfect_hash = index_.perfect_hash(k); if (__builtin_expect(present_[perfect_hash], true)) { return perfect_hash; } } + if (__builtin_expect(!slack_.empty(), 0)) { + auto sit = slack_.find(hasher128_.hash128(k, 0)); + if (sit != slack_.end()) return sit->second; + } return -1; }