0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-02 09:46:52 -05:00

Merge bitcoin/bitcoin#30326: optimization: Reduce cache lookups in CCoinsViewCache::FetchCoin

204ca67bba 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: https://github.com/bitcoin/bitcoin/pull/30326#issuecomment-2188378721

ACKs for top commit:
  sipa:
    utACK 204ca67bba
  achow101:
    ACK 204ca67bba
  andrewtoth:
    re-ACK 204ca67bba

Tree-SHA512: 65743a5d4edd442672a59d7b3de38fe197c61270a5c8df65712413904559f360fc58b512234558c7e5169ffb4dda3b2d2f7ded92ad5b04ca999828986b251066
This commit is contained in:
Ava Chow 2024-08-12 16:16:58 -04:00
commit 34ea7508d4
No known key found for this signature in database
GPG key ID: 17565732E08E5E41

View file

@ -43,19 +43,18 @@ size_t CCoinsViewCache::DynamicMemoryUsage() const {
}
CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
CCoinsMap::iterator it = cacheCoins.find(outpoint);
if (it != cacheCoins.end())
return it;
Coin tmp;
if (!base->GetCoin(outpoint, tmp))
return cacheCoins.end();
CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
if (ret->second.coin.IsSpent()) {
// The parent only has an empty entry for this outpoint; we can consider our
// version as fresh.
ret->second.AddFlags(CCoinsCacheEntry::FRESH, *ret, m_sentinel);
const auto [ret, inserted] = cacheCoins.try_emplace(outpoint);
if (inserted) {
if (!base->GetCoin(outpoint, ret->second.coin)) {
cacheCoins.erase(ret);
return cacheCoins.end();
}
if (ret->second.coin.IsSpent()) {
// The parent only has an empty entry for this outpoint; we can consider our version as fresh.
ret->second.AddFlags(CCoinsCacheEntry::FRESH, *ret, m_sentinel);
}
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
}
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
return ret;
}