eth/fetcher: lazy-allocate hashes slice in scheduleFetches

scheduleFetches.func1 is the biggest allocator in the long-duration
profile of node (11% of total alloc_space).
Each peer-iteration pre-allocated make([]common.Hash, 0, maxTxRetrievals),
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.
This commit is contained in:
Bosul Mun 2026-04-24 13:24:52 +02:00 committed by GitHub
commit 0da22dee45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -992,7 +992,7 @@ func (f *TxFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{},
return // continue in the for-each
}
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 +1009,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 {