#35195 coins: cache UTXO outpoint hash codes
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #35195 coins: cache UTXO outpoint hash codes | Author silent 183d | 0 | Strong | 4 + 17 tests | |||
|
|
|
|
| |||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
Removes the `noexcept` specification from `SaltedOutpointHasher::operator()` to induce `libstdc++`'s `std::unordered_map` to cache hash codes within node structures. This effectively reverts PR #16957, trading a node-size memory increase of one `size_t` for reduced SipHash recomputations during UTXO map operations. A unit test is also added to check invocability and the `libstdc++` fast-hash trait.
Problem: In `libstdc++`, `std::unordered_map` omits cached hash codes in bucket nodes when the hash functor is marked `noexcept`, forcing table lookups and rehashing in `CCoinsMap` to repeatedly recompute outpoint hashes with SipHash. While PR #16957 introduced `noexcept` to reduce memory usage per node by about 9%, it introduced a runtime penalty.
Evidence of importance:
- Author's benchmarks show reindex-chainstate and IBD completing approximately 2% to 3% faster with cached hash codes across different `-dbcache` settings.
- Author reports up to ~11% speedup during AssumeUTXO loading (`loadtxoutset`), which isolates the coins cache performance from block validation overhead.
- Author's Massif profiling showed memory usage was roughly neutral at moderate `-dbcache` values, but increased at very high cache sizes (24.11 GB to 25.49 GB peak RSS).
Scope: Relies on implementation-defined behavior in libstdc++ where non-noexcept fast hash functions cause unordered containers to store cached hash values in nodes. The unit test uses the internal libstdc++ header `<bits/functional_hash.h>` and `std::__is_fast_hash` under `__GLIBCXX__`.
Reviewability
Stale · Author silent 183d
No author activity for 183 days; a review may wait a long time for a response.
Agreement
Strong
substantive support, no open objection (optout21)
Thread notes: optout21 provided a substantive Concept ACK based on benchmark results. Their inline question regarding __is_fast_hash was not recorded as an objection because optout21 explicitly noted having no issues or dangers with reverting noexcept and categorized the inline remarks as nits.
Objections, suggestions, and questions: none recorded.
Support:
- optout21 (contributor) (Concept ACK, 2026-05-28): In general, the tradeoff between extra memory and extra CPU is not clear, but in this case benchmarks indicate that caching (more memory, less CPU) results in faster execution, therefore it should be applied.
Participants:
- optout21 (contributor, support, 5 statements 2026-05-28 to 2026-05-28): Concept ACK citing benchmark performance gains; asked an inline question about __is_fast_hash and left nits
Files
17 lines under test/bench/ci.
- src/test/hash_tests.cpp +17/-0
- src/util/hasher.h +4/-7
Card
The short text the ranking pass compares across PRs.
This PR marks SaltedOutpointHasher as noexcept(false) to prompt libstdc++ unordered containers to cache hash codes in their nodes. This intentionally reverses the tradeoff made in PR #16957, prioritizing CPU speed over per-node memory savings in the UTXO cache. The author's benchmarks demonstrate a 2% to 3% runtime improvement during IBD and reindex-chainstate, and up to an 11% speedup during AssumeUTXO loading, at the cost of higher peak memory on very large dbcache configurations.
Data
thread read through 2026-05-28 (5 statements), head 16e77fdf13
Discussion read under schema 1 rules: suggestions and questions may be missing, and an objection may combine several harms (schema history).
labels: UTXO Db and Indexes, Needs rebase · draft
Categories
Validation
P3 · speedup (ranking pass: Moved up: measured IBD and assumeutxo-loading gains make it the most tangible P3 item after the bug fixes)
Provides a modest 2% to 3% speedup to IBD/reindex and ~11% during AssumeUTXO loading, traded against higher memory usage per cache node. Benchmarks demonstrate reduced SipHash recomputation in `CCoinsMap`, but the optimization relies on implementation-defined `libstdc++` behavior and is reasonably deferrable.
Membership: Carries the 'UTXO Db and Indexes' label and modifies hashing behavior specifically to optimize the in-memory UTXO cache (`CCoinsMap`) during IBD and AssumeUTXO loading.
Factors: security/stability 0, bug 0, performance 1, user value 0, leverage 0