From a1a820d3c98a7f2bdb5547ebede3b2f281e5e6e2 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Mon, 11 Apr 2022 05:22:05 +0100 Subject: [PATCH] Avoid heap allocation in GetRequestablePieces (#734) The calculation of whether we should ignore a piece in GetRequestablePieces ends up doing an allocation for every piece, when all we really need to do is query the index in the torrent. Provide an IgnorePiece function instead, which avoids the need for a temporary allocation. Observed to cut out 40% of object allocations in some workloads (large download, lots of seeds). --- request-strategy-impls.go | 11 +++++++++-- request-strategy/order.go | 3 +-- request-strategy/torrent.go | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/request-strategy-impls.go b/request-strategy-impls.go index f4c12646..bf3e4083 100644 --- a/request-strategy-impls.go +++ b/request-strategy-impls.go @@ -44,8 +44,15 @@ type requestStrategyTorrent struct { t *Torrent } -func (r requestStrategyTorrent) Piece(i int) request_strategy.Piece { - return requestStrategyPiece{r.t, i} +func (r requestStrategyTorrent) IgnorePiece(i int) bool { + if r.t.ignorePieceForRequests(i) { + return true + } + if r.t.pieceNumPendingChunks(i) == 0 { + return true + } + + return false } func (r requestStrategyTorrent) ChunksPerPiece() uint32 { diff --git a/request-strategy/order.go b/request-strategy/order.go index 130c698b..09f1ff0c 100644 --- a/request-strategy/order.go +++ b/request-strategy/order.go @@ -54,7 +54,6 @@ func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(ih metainf pro.tree.Scan(func(_i pieceRequestOrderItem) bool { ih := _i.key.InfoHash var t Torrent = input.Torrent(ih) - var piece Piece = t.Piece(_i.key.Index) pieceLength := t.PieceLength() if storageLeft != nil { if *storageLeft < pieceLength { @@ -62,7 +61,7 @@ func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(ih metainf } *storageLeft -= pieceLength } - if !piece.Request() || piece.NumPendingChunks() == 0 { + if t.IgnorePiece(_i.key.Index) { // TODO: Clarify exactly what is verified. Stuff that's being hashed should be // considered unverified and hold up further requests. return true diff --git a/request-strategy/torrent.go b/request-strategy/torrent.go index 51fc1a6c..2460f2e4 100644 --- a/request-strategy/torrent.go +++ b/request-strategy/torrent.go @@ -1,7 +1,7 @@ package request_strategy type Torrent interface { - Piece(int) Piece + IgnorePiece(int) bool ChunksPerPiece() uint32 PieceLength() int64 } -- 2.48.1