perf: reduce per-tx allocations with O(1) lookups and capacity hints #188
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Reduces per-transaction memory allocations by eliminating redundant method calls and replacing O(n) slice iterations with O(1) map lookups.
Key optimizations:
GetProgramIDs()once per transaction (~0.82 GB savings estimated)slices.Contains()with precomputed map lookups in hot pathsNewReservedAcctsSetto avoid drift between packagesChanges
1. GetProgramIDs Caching
Problem:
GetProgramIDs()was being called insideisWritable()— once per account per transaction. For a typical tx with 10 accounts, this meant 10 redundant slice allocations.Solution: Build
programIDSetmap once per transaction, pass toisWritable():2. slices.Contains → Map Lookups
isWritable()reserved accountsisWritable()program IDsrecordStakeAndVoteAccounts()writable checksealevel.IsWritable()3. Capacity Hints
Added capacity hints to hot-path maps to reduce GC pressure:
accounts.goinstructionAcctPubkeyslen(tx.Message.AccountKeys)accounts.govalidatedLoaders4(usually ≤4 loaders)transaction.goModifiedVoteStates8topsort_planner.gopkToAcctlen(b.TxMetas)*4block.goalreadyAddedlen(slotCtx.WritableAccts)4. Code Consolidation
Exported
NewReservedAcctsSetfrompkg/sealevelso bothtransaction.goandsealevel.gouse the same set, preventing drift.Files Changed
pkg/replay/transaction.go— Main isWritable changes, programIDSet, writablePubkeySetpkg/sealevel/sealevel.go— IsWritable signature, exported NewReservedAcctsSetpkg/rent/rent.go— Updated to use programIDSetpkg/replay/accounts.go— Capacity hintspkg/replay/topsort_planner.go— Capacity hintpkg/replay/block.go— Capacity hintTest Plan
go build ./...passesgo test ./pkg/replay/... ./pkg/sealevel/... ./pkg/rent/...passesalloc MB/sin 100-slot summary — should decreaseExpected Impact
Based on pprof analysis:
🤖 Generated with Claude Code