Skip to content

Commit

Permalink
make SaltedOutpointHasher noexcept
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
martinus committed Sep 25, 2019
1 parent 742cd77 commit 67d9990
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,16 @@ class SaltedOutpointHasher
* 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);
}
};
Expand Down

0 comments on commit 67d9990

Please sign in to comment.