node: optimize CBlockIndexWorkComparator

Refactor the comparator logic in CBlockIndexWorkComparator::operator() to reduce the amounts of branches and improve readability without changing semantics.

The previous implementation used multiple separate comparisons with explicit branches for greater-than and less-than cases, resulting in
unnecessary code paths.

The new implementation consolidates comparisons into single inequality checks and reduces complexity while preserving its original behavior.
This change is particularly beneficial for loading blocks from files and reindexing.

taskset -c 1 ./bin/bench_bitcoin --filter="(CheckBlockIndex|LoadExternalBlockFile|BlockToJsonVerboseWrite)" -output-csv=bench_old.csv --min-time=30000

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|       26,557,419.20 |               37.65 |    0.1% |     32.85 | `BlockToJsonVerboseWrite`
|          129,988.82 |            7,692.97 |    0.0% |     33.02 | `CheckBlockIndex`
|       21,661,396.96 |               46.17 |    0.5% |     32.37 | `LoadExternalBlockFile`

taskset -c 1 ./bin/bench_bitcoin --filter="(CheckBlockIndex|LoadExternalBlockFile|BlockToJsonVerboseWrite|WalletIsMineDescriptors)" -output-csv=bench_new.csv --min-time=30000

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|       27,930,130.95 |               35.80 |    0.1% |     32.96 | `BlockToJsonVerboseWrite`
|          115,346.65 |            8,669.52 |    0.0% |     33.00 | `CheckBlockIndex`
|       20,389,679.85 |               49.04 |    0.4% |     31.76 | `LoadExternalBlockFile`
This commit is contained in:
Raimo33 2025-09-07 02:00:00 +02:00
parent 36e40417de
commit 80ac0467ef
No known key found for this signature in database
GPG Key ID: 6B501BF2708B3036
1 changed files with 7 additions and 9 deletions

View File

@ -158,20 +158,18 @@ namespace node {
bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
{
// First sort by most total work, ...
if (pa->nChainWork > pb->nChainWork) return false;
if (pa->nChainWork < pb->nChainWork) return true;
if (pa->nChainWork != pb->nChainWork) {
return pa->nChainWork < pb->nChainWork;
}
// ... then by earliest time received, ...
if (pa->nSequenceId < pb->nSequenceId) return false;
if (pa->nSequenceId > pb->nSequenceId) return true;
if (pa->nSequenceId != pb->nSequenceId) {
return pa->nSequenceId > pb->nSequenceId;
}
// Use pointer address as tie breaker (should only happen with blocks
// loaded from disk, as those all have id 0).
if (pa < pb) return false;
if (pa > pb) return true;
// Identical blocks.
return false;
return pa > pb;
}
bool CBlockIndexHeightOnlyComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const