From 0d10a1b53afb425d1cabf3a0ebd5ebb56e550822 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 10 Sep 2021 21:48:44 +1000 Subject: [PATCH] Optimize Torrent.worstBadConn --- go.mod | 2 +- go.sum | 2 ++ torrent.go | 27 ++++++++++++++++++++------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 144bc7fd..dcbe602c 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508 github.com/RoaringBitmap/roaring v0.9.4 github.com/alexflint/go-arg v1.4.2 - github.com/anacrolix/chansync v0.1.1-0.20210904130811-9cd7139c8dd9 + github.com/anacrolix/chansync v0.2.1-0.20210910114620-14955c95ded9 github.com/anacrolix/confluence v1.8.0 // indirect github.com/anacrolix/dht/v2 v2.10.5-0.20210902001729-06cc4fe90e53 github.com/anacrolix/envpprof v1.1.1 diff --git a/go.sum b/go.sum index af23d4b5..4dc4fcef 100644 --- a/go.sum +++ b/go.sum @@ -49,6 +49,8 @@ github.com/anacrolix/chansync v0.1.0 h1:4cIfJmEV8sYkSEMW2AXnPjX6iQT4plqELJ65pLna github.com/anacrolix/chansync v0.1.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k= github.com/anacrolix/chansync v0.1.1-0.20210904130811-9cd7139c8dd9 h1:Jk3Mdr+XbO1uvf/+nUXjb/M1dPDNPQThxKmS5MLGE+w= github.com/anacrolix/chansync v0.1.1-0.20210904130811-9cd7139c8dd9/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k= +github.com/anacrolix/chansync v0.2.1-0.20210910114620-14955c95ded9 h1:jfSupvl9p7Bkd9snD6DrjxDmsYjJeYxSqhQa/I9wV3I= +github.com/anacrolix/chansync v0.2.1-0.20210910114620-14955c95ded9/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k= github.com/anacrolix/confluence v1.7.1-0.20210221224747-9cb14aa2c53a/go.mod h1:T0JHvSaf9UfoiUdCtCOUuRroHm/tauUJTbLc6/vd5YA= github.com/anacrolix/confluence v1.7.1-0.20210221225853-90405640e928/go.mod h1:NoLcfoRet+kYttjLXJRmh4qBVrylJsfIItik5GGj21A= github.com/anacrolix/confluence v1.7.1-0.20210311004351-d642adb8546c/go.mod h1:KCZ3eObqKECNeZg0ekAoJVakHMP3gAdR8i0bQ26IkzM= diff --git a/torrent.go b/torrent.go index b719529f..27ad3e1e 100644 --- a/torrent.go +++ b/torrent.go @@ -263,14 +263,13 @@ func (t *Torrent) addrActive(addr string) bool { return false } -func (t *Torrent) unclosedConnsAsSlice() (ret []*PeerConn) { - ret = make([]*PeerConn, 0, len(t.conns)) +func (t *Torrent) appendUnclosedConns(ret []*PeerConn) []*PeerConn { for c := range t.conns { if !c.closed.IsSet() { ret = append(ret, c) } } - return + return ret } func (t *Torrent) addPeer(p PeerInfo) (added bool) { @@ -974,11 +973,25 @@ func (t *Torrent) wantPieceIndex(index pieceIndex) bool { }) } +// A pool of []*PeerConn, to reduce allocations in functions that need to index or sort Torrent +// conns (which is a map). +var peerConnSlices sync.Pool + // The worst connection is one that hasn't been sent, or sent anything useful for the longest. A bad -// connection is one that usually sends us unwanted pieces, or has been in worser half of the -// established connections for more than a minute. -func (t *Torrent) worstBadConn() *PeerConn { - wcs := worseConnSlice{t.unclosedConnsAsSlice()} +// connection is one that usually sends us unwanted pieces, or has been in the worse half of the +// established connections for more than a minute. This is O(n log n). If there was a way to not +// consider the position of a conn relative to the total number, it could be reduced to O(n). +func (t *Torrent) worstBadConn() (ret *PeerConn) { + var sl []*PeerConn + getInterface := peerConnSlices.Get() + if getInterface == nil { + sl = make([]*PeerConn, 0, len(t.conns)) + } else { + sl = getInterface.([]*PeerConn)[:0] + } + sl = t.appendUnclosedConns(sl) + defer peerConnSlices.Put(sl) + wcs := worseConnSlice{sl} heap.Init(&wcs) for wcs.Len() != 0 { c := heap.Pop(&wcs).(*PeerConn) -- 2.48.1