diff options
author | Martin Ankerl <martin.ankerl@gmail.com> | 2019-09-24 20:54:58 +0200 |
---|---|---|
committer | Martin Ankerl <martin.ankerl@gmail.com> | 2019-09-25 20:56:38 +0200 |
commit | 67d99900b0d770038c9c5708553143137b124a6c (patch) | |
tree | 4f08c47dbd31967b616d7dcc93d7e228aaad9a8a | |
parent | 742cd77f6f9017425e8f757e2d1297c712bc4140 (diff) |
make SaltedOutpointHasher noexcept
If the hash is not noexcept, unorderd_map has to assume that it can throw an exception. Thus when rehashing care needs to be taken. libstdc++ solves this by simply caching the hash value, which increases memory of each node by 8 bytes. Adding noexcept prevents this caching. In my experiments with -reindex-chainstate -stopatheight=594000, memory usage has decreased by 9.4% while runtime has increased by 1.6% due to additional hashing. Additionally, memusage::DynamicUsage() is now more accurate and does not underestimate.
-rw-r--r-- | src/coins.h | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/coins.h b/src/coins.h index dca1beabb6..d8135e0d9a 100644 --- a/src/coins.h +++ b/src/coins.h @@ -95,8 +95,16 @@ public: * This *must* return size_t. With Boost 1.46 on 32-bit systems the * unordered_map will behave unpredictably if the custom hasher returns a * uint64_t, resulting in failures when syncing the chain (#4634). + * + * Having the hash noexcept allows libstdc++'s unordered_map to recalculate + * the hash during rehash, so it does not have to cache the value. This + * reduces node's memory by sizeof(size_t). The required recalculation has + * a slight performance penalty (around 1.6%), but this is compensated by + * memory savings of about 9% which allow for a larger dbcache setting. + * + * @see https://gcc.gnu.org/onlinedocs/gcc-9.2.0/libstdc++/manual/manual/unordered_associative.html */ - size_t operator()(const COutPoint& id) const { + size_t operator()(const COutPoint& id) const noexcept { return SipHashUint256Extra(k0, k1, id.hash, id.n); } }; |