Skip to content

Commit 0b3609e

Browse files
committed
docs(perf): matching the block source moves the ratio to 1.42x
Every prior number fetched over REST from a live bitcoind while Core read local blk files. Reading a local block file instead: 84.6s against 121.9s, and apply itself improves 82.0s to 76.7s because the serving node is no longer competing for CPU. Against Core's 59.6s the honest ratio is 1.42x, not 2.05x. The earlier figures measured the harness as much as the engine and are marked superseded.
1 parent c5d9f86 commit 0b3609e

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

docs/solutions/performance-issues/txid-parallelization-delivers-2x-but-core-still-leads.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Beats GoCoin 2.3x and uses 2.8x less memory than Core, but Core still leads 2.05x on throughput
2+
title: Beats GoCoin 2.3x, uses 2.9x less memory than Core, and Core leads 1.42x on throughput once the harness is matched
33
date: 2026-08-07
44
category: docs/solutions/performance-issues
55
module: node apply path (crates/node/src/apply.rs, crates/consensus/src/verify_tx.rs)
@@ -21,7 +21,7 @@ tags:
2121
- replay
2222
---
2323

24-
# Beats GoCoin 2.3×, uses 2.8× less memory than Core, and Core still leads 2.05× on throughput
24+
# Beats GoCoin 2.3×, uses 2.9× less memory than Core, and Core leads 1.42× once the harness is matched
2525

2626
## Context
2727

@@ -132,6 +132,27 @@ The first two cleared the tests but not the 1.05× noise floor; the third never
132132

133133
The fourth result retires the "FFI boundary is the remaining lever" hypothesis for its allocation half. Per-input `ScriptPubkey::new` is a ~25-byte `malloc` plus copy; at 3.3M inputs that is real allocator traffic, and removing it entirely changed nothing measurable. What the kernel spends inside `btck_script_pubkey_verify` is secp256k1 work, not marshalling. Marshalling-side micro-optimization is now closed as a class: four separate attempts (parallel prepare, serialize buffer, witness-free skip, prevout reuse) all landed at 0.98–1.00×.
134134

135+
## Matching the harness moved the ratio from 2.05× to 1.42×
136+
137+
Every earlier number here fetched blocks over REST from a live `bitcoind`. Core's `-reindex-chainstate` reads its own `blk*.dat` files. That is not a like-for-like harness: the replay paid HTTP round-trips *and* competed for CPU with the process serving them, neither of which Core pays.
138+
139+
`mainnet_prefix_replay --blocks-file` now reads a length-prefixed local file, mirroring what Core does. Same window, same validation posture, pinned 3× medians:
140+
141+
| Source | elapsed | apply | outside apply |
142+
|---|---|---|---|
143+
| REST from live `bitcoind` | 121.9s | 82.0s | ~40s |
144+
| **local block file** | **84.6s** (84.2, 84.6, 86.5) | **76.7s** | 8.0s |
145+
146+
Note that *apply itself* improved, 82.0s → 76.7s, purely from removing the serving node's CPU contention. The harness was distorting the engine measurement, not merely adding a constant.
147+
148+
| Metric | Core 31.0 | bitcoin-rs | |
149+
|---|---|---|---|
150+
| elapsed | 59.6s | **84.6s** | **1.42× slower** |
151+
| apply | 55.80s | 76.7s | 1.37× slower |
152+
| peak RSS | 643 MB | **224 MB** | **2.87× leaner** |
153+
154+
**Quote 1.42×.** The 2.05× and 2.22× figures earlier in this note measured the harness as much as the engine and are superseded. The lesson is the same one that produced the matched-pair section below: a ratio is only as good as the least-matched thing in it, and here the block source was the least-matched thing for the whole session.
155+
135156
## The matched pair — the only ratio worth quoting
136157

137158
Every earlier ratio in this note compared a bitcoin-rs median against Core's **67s** figure captured on 2026-06-09 under unknown load. That reference has now been re-derived, and the honest numbers are worse than the ones this document previously carried.

0 commit comments

Comments
 (0)