summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-06-04 07:57:04 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2021-06-04 07:57:04 +0000
commit2e152707c1266df3c39c60cde5f9db6a40221c9b (patch)
treeee781d7a2fdead5214044010a92f6972a836d8fd /vespalib
parent3f1358a589375cd228143505b6e0081c20f5c353 (diff)
- Add benchmark for hashtable reconstruction.
- Optimize by not initializing hash_node._node char array. - Also skip reconstruction, if it is in initial state.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/stllike/hashtable_test.cpp21
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hashtable.h4
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hashtable.hpp2
3 files changed, 26 insertions, 1 deletions
diff --git a/vespalib/src/tests/stllike/hashtable_test.cpp b/vespalib/src/tests/stllike/hashtable_test.cpp
index cbd8b28d9a8..5f6f1601c84 100644
--- a/vespalib/src/tests/stllike/hashtable_test.cpp
+++ b/vespalib/src/tests/stllike/hashtable_test.cpp
@@ -134,6 +134,27 @@ TEST("require that hashtable<vector<int>> can be copied") {
EXPECT_EQUAL(6, (*table.find(2))[2]);
}
+/**
+ * Test to profile destruction and recreation of hash map.
+ * It revealed some unexpected behaviour. Results with 10k iterations on 2018 macbook pro 2.6 Ghz i7
+ * 1 - previous - 14.7s hash_node() : _node(), _next(invalid) {}
+ * 2 - test - 6.6s hash_node() : _next(invalid) { memset(_node, 0, sizeof(node)); }
+ * 3 - current - 2.3s hash_node() : _next(invalid) {}
+ */
+TEST("benchmark clear") {
+ vespalib::hash_map<uint32_t, uint32_t> m(1000000);
+ constexpr size_t NUM_ITER = 10; // Set to 1k-10k to get measurable numbers 10k ~= 2.3s
+ for (size_t i(0); i < NUM_ITER; i++) {
+ m[46] = 17;
+ EXPECT_FALSE(m.empty());
+ EXPECT_EQUAL(1u, m.size());
+ EXPECT_EQUAL(1048576u, m.capacity());
+ m.clear();
+ EXPECT_TRUE(m.empty());
+ EXPECT_EQUAL(1048576u, m.capacity());
+ }
+}
+
} // namespace
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.h b/vespalib/src/vespa/vespalib/stllike/hashtable.h
index b94672aaa06..ede18f89dc2 100644
--- a/vespalib/src/vespa/vespalib/stllike/hashtable.h
+++ b/vespalib/src/vespa/vespalib/stllike/hashtable.h
@@ -102,7 +102,9 @@ class hash_node {
public:
using next_t=hashtable_base::next_t;
enum {npos=-1u, invalid=-2u};
- hash_node() : _node(), _next(invalid) {}
+ hash_node()
+ : _next(invalid)
+ {}
hash_node(const V & node, next_t next=npos)
: _next(next)
{
diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.hpp b/vespalib/src/vespa/vespalib/stllike/hashtable.hpp
index d80113a8f55..494dc223f5b 100644
--- a/vespalib/src/vespa/vespalib/stllike/hashtable.hpp
+++ b/vespalib/src/vespa/vespalib/stllike/hashtable.hpp
@@ -146,6 +146,8 @@ hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::erase(const Key & key
template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator >
void
hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::clear() {
+ if (_count == 0) return; // Already empty and properly initialized
+
_nodes.clear();
_count = 0;
_nodes.resize(getTableSize());