Skip to content

Commit 34ea750

Browse files
committed
Merge bitcoin/bitcoin#30326: optimization: Reduce cache lookups in CCoinsViewCache::FetchCoin
204ca67 Reduce cache lookups in CCoinsViewCache::FetchCoin (Lőrinc) Pull request description: Enhanced efficiency and readability of `CCoinsViewCache::FetchCoin` by replacing separate `find()` and `emplace()` calls with a single `try_emplace()`, reducing map lookups and potential insertions. `AssembleBlock` shows `FetchCoin` as one of its bottlenecks: <img src="https://github.com/bitcoin/bitcoin/assets/1841944/79c7f480-aac2-46da-9ac9-526a02a8eafa"> These changes result in a modest performance improvement: > ./src/bench/bench_bitcoin --filter='AssembleBlock' --min-time=10000 before: | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 156,160.70 | 6,403.66 | 0.6% | 10.91 | `AssembleBlock` after: | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 152,971.97 | 6,537.15 | 0.2% | 10.95 | `AssembleBlock` Further benchmarks: bitcoin/bitcoin#30326 (comment) ACKs for top commit: sipa: utACK 204ca67 achow101: ACK 204ca67 andrewtoth: re-ACK 204ca67 Tree-SHA512: 65743a5d4edd442672a59d7b3de38fe197c61270a5c8df65712413904559f360fc58b512234558c7e5169ffb4dda3b2d2f7ded92ad5b04ca999828986b251066
2 parents ee57737 + 204ca67 commit 34ea750

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

src/coins.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,18 @@ size_t CCoinsViewCache::DynamicMemoryUsage() const {
4343
}
4444

4545
CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
46-
CCoinsMap::iterator it = cacheCoins.find(outpoint);
47-
if (it != cacheCoins.end())
48-
return it;
49-
Coin tmp;
50-
if (!base->GetCoin(outpoint, tmp))
51-
return cacheCoins.end();
52-
CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
53-
if (ret->second.coin.IsSpent()) {
54-
// The parent only has an empty entry for this outpoint; we can consider our
55-
// version as fresh.
56-
ret->second.AddFlags(CCoinsCacheEntry::FRESH, *ret, m_sentinel);
46+
const auto [ret, inserted] = cacheCoins.try_emplace(outpoint);
47+
if (inserted) {
48+
if (!base->GetCoin(outpoint, ret->second.coin)) {
49+
cacheCoins.erase(ret);
50+
return cacheCoins.end();
51+
}
52+
if (ret->second.coin.IsSpent()) {
53+
// The parent only has an empty entry for this outpoint; we can consider our version as fresh.
54+
ret->second.AddFlags(CCoinsCacheEntry::FRESH, *ret, m_sentinel);
55+
}
56+
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
5757
}
58-
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
5958
return ret;
6059
}
6160

0 commit comments

Comments
 (0)