From 2ca74d2ef9314c18a70e396858ddc6dc7de2350f Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Wed, 22 Apr 2026 17:55:43 +0000 Subject: [PATCH] eth/fetcher: lazy-allocate hashes slice in scheduleFetches scheduleFetches.func1 is the single biggest allocator in the Pyroscope profile of a busy node (~13.5 GB/hr, 8% of total alloc_space). Each peer-iteration pre-allocated 'make([]common.Hash, 0, maxTxRetrievals)' = 8 KB, even for peers that end up collecting no new hashes (all their announces were already being fetched by someone else). Defer the slice allocation to the first append. Peers that collect zero hashes now pay zero allocation, which is the common case on the timeoutTrigger path where all peers with any announces are iterated. New benchmarks BenchmarkScheduleFetches_{100peers_10new, 100peers_allFetching, 500peers_3new} (benchstat, 6 samples): scenario ns/op B/op allocs/op 100p/10new unchanged unchanged unchanged (fast path) 100p/allFetching -62% -92% -20% 500p/3new -22% -44% -7% geomean -33% -65% -9% --- eth/fetcher/tx_fetcher.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 5817dfbcf5..2165b7f103 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -991,8 +991,10 @@ func (f *TxFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}, if len(f.announces[peer]) == 0 { return // continue in the for-each } + // hashes is allocated lazily: peers that collect no new hashes + // (all announces already being fetched) skip the 8KB allocation. var ( - hashes = make([]common.Hash, 0, maxTxRetrievals) + hashes []common.Hash bytes uint64 ) f.forEachAnnounce(f.announces[peer], func(hash common.Hash, meta txMetadata) bool { @@ -1009,6 +1011,9 @@ func (f *TxFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}, f.alternates[hash] = f.announced[hash] delete(f.announced, hash) + if hashes == nil { + hashes = make([]common.Hash, 0, maxTxRetrievals) + } // Accumulate the hash and stop if the limit was reached hashes = append(hashes, hash) if len(hashes) >= maxTxRetrievals {