From 869363a210d278330bfcba4a5aec82281f12b086 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Thu, 8 Jan 2015 01:35:45 -0500 Subject: [PATCH] Switch peer.requestQueue from linked list to slice. Only two operations are performed with this data structure: adding to the back and removing from the front. Because middle inserts and deletions are never needed, a linked list results in overall worse performance due to an extra allocation for each element's node, worse cache locality, and the runtime cost of boxing/unboxing each item during accesses. On top of the performance gains, a slice is more type safe as it is a true generic data structure making it is impossible to insert or access an element with the wrong type. --- blockmanager.go | 10 ++++++---- peer.go | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/blockmanager.go b/blockmanager.go index 6306fa50..42439f88 100644 --- a/blockmanager.go +++ b/blockmanager.go @@ -930,7 +930,7 @@ func (b *blockManager) handleInvMsg(imsg *invMsg) { } if !haveInv { // Add it to the request queue. - imsg.peer.requestQueue.PushBack(iv) + imsg.peer.requestQueue = append(imsg.peer.requestQueue, iv) continue } @@ -980,9 +980,10 @@ func (b *blockManager) handleInvMsg(imsg *invMsg) { numRequested := 0 gdmsg := btcwire.NewMsgGetData() requestQueue := imsg.peer.requestQueue - for e := requestQueue.Front(); e != nil; e = requestQueue.Front() { - iv := e.Value.(*btcwire.InvVect) - imsg.peer.requestQueue.Remove(e) + for len(requestQueue) != 0 { + iv := requestQueue[0] + requestQueue[0] = nil + requestQueue = requestQueue[1:] switch iv.Type { case btcwire.InvTypeBlock: @@ -1010,6 +1011,7 @@ func (b *blockManager) handleInvMsg(imsg *invMsg) { break } } + imsg.peer.requestQueue = requestQueue if len(gdmsg.InvList) > 0 { imsg.peer.QueueMessage(gdmsg, nil) } diff --git a/peer.go b/peer.go index a4762660..c6536ade 100644 --- a/peer.go +++ b/peer.go @@ -162,7 +162,7 @@ type peer struct { prevGetBlocksStop *btcwire.ShaHash // owned by blockmanager prevGetHdrsBegin *btcwire.ShaHash // owned by blockmanager prevGetHdrsStop *btcwire.ShaHash // owned by blockmanager - requestQueue *list.List + requestQueue []*btcwire.InvVect filter *bloom.Filter relayMtx sync.Mutex disableRelayTx bool @@ -1890,7 +1890,6 @@ func newPeerBase(s *server, inbound bool) *peer { knownInventory: NewMruInventoryMap(maxKnownInventory), requestedTxns: make(map[btcwire.ShaHash]struct{}), requestedBlocks: make(map[btcwire.ShaHash]struct{}), - requestQueue: list.New(), filter: bloom.LoadFilter(nil), outputQueue: make(chan outMsg, outputBufferSize), sendQueue: make(chan outMsg, 1), // nonblocking sync