Pre-allocate space for high use slices.
This commit modifies the code to choose sane defaults for the backing arrays for slices that involve a lot of appends such block locators, hash processing, and needed transactions. This is an optimization to avoid the overhead of growing the backing arrays and copying the data multiple times in the most common case. This also prevents a leak in Go GC which will likely ultimatley be fixed, but the efficiecy gains alone are worth the change.
This commit is contained in:
parent
d1f1fe0752
commit
2f743b4821
3 changed files with 19 additions and 3 deletions
|
@ -29,7 +29,8 @@ type BlockLocator []*btcwire.ShaHash
|
|||
// consist of the passed hash
|
||||
func (b *BlockChain) BlockLocatorFromHash(hash *btcwire.ShaHash) BlockLocator {
|
||||
// The locator contains the requested hash at the very least.
|
||||
locator := BlockLocator([]*btcwire.ShaHash{hash})
|
||||
locator := make(BlockLocator, 0, btcwire.MaxBlockLocatorsPerMsg)
|
||||
locator = append(locator, hash)
|
||||
|
||||
// Nothing more to do if a locator for the genesis hash was requested.
|
||||
if hash.IsEqual(b.chainParams().GenesisHash) {
|
||||
|
|
|
@ -38,10 +38,15 @@ func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool {
|
|||
// It repeats the process for the newly accepted blocks (to detect further
|
||||
// orphans which may no longer be orphans) until there are no more.
|
||||
func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error {
|
||||
processHashes := []*btcwire.ShaHash{hash}
|
||||
// Start with processing at least the passed hash. Leave a little room
|
||||
// for additional orphan blocks that need to be processed without
|
||||
// needing to grow the array in the common case.
|
||||
processHashes := make([]*btcwire.ShaHash, 0, 10)
|
||||
processHashes = append(processHashes, hash)
|
||||
for len(processHashes) > 0 {
|
||||
// Pop the first hash to process from the slice.
|
||||
processHash := processHashes[0]
|
||||
processHashes[0] = nil // Prevent GC leak.
|
||||
processHashes = processHashes[1:]
|
||||
|
||||
// Look up all orphans that are parented by the block we just
|
||||
|
|
12
txlookup.go
12
txlookup.go
|
@ -215,10 +215,20 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc
|
|||
txInFlight[*txHash] = i
|
||||
}
|
||||
|
||||
// Make a reasonable guess for the maximum number of needed input
|
||||
// transactions to use as the starting point for the needed transactions
|
||||
// array. The array will dynamically grow as needed, but it's much less
|
||||
// overhead to avoid growing and copying the array multiple times in the
|
||||
// common case. Each block usually has no more than ten inputs per
|
||||
// transaction, so use that as a reasonable starting point. A block
|
||||
// with 2,000 transactions would only result in around 156KB on a 64-bit
|
||||
// system using this approach.
|
||||
maxNeededHint := (len(transactions) - 1) * 10
|
||||
txNeededList := make([]*btcwire.ShaHash, 0, maxNeededHint)
|
||||
|
||||
// Loop through all of the transaction inputs (except for the coinbase
|
||||
// which has no inputs) collecting them into lists of what is needed and
|
||||
// what is already known (in-flight).
|
||||
var txNeededList []*btcwire.ShaHash
|
||||
txStore := make(map[btcwire.ShaHash]*txData)
|
||||
for i, tx := range transactions[1:] {
|
||||
for _, txIn := range tx.TxIn {
|
||||
|
|
Loading…
Reference in a new issue