Skip to content

Commit 6c59355

Browse files
committed
perf: preallocate slices on swarm and protocol hot paths
1 parent ec408fc commit 6c59355

9 files changed

Lines changed: 29 additions & 16 deletions

File tree

core/protocol/id.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ const (
1111
// ConvertFromStrings is a convenience function that takes a slice of strings and
1212
// converts it to a slice of protocol.ID.
1313
func ConvertFromStrings(ids []string) (res []ID) {
14-
res = make([]ID, 0, len(ids))
15-
for _, id := range ids {
16-
res = append(res, ID(id))
14+
res = make([]ID, len(ids))
15+
for i, id := range ids {
16+
res[i] = ID(id)
1717
}
1818
return res
1919
}
2020

2121
// ConvertToStrings is a convenience function that takes a slice of protocol.ID and
2222
// converts it to a slice of strings.
2323
func ConvertToStrings(ids []ID) (res []string) {
24-
res = make([]string, 0, len(ids))
25-
for _, id := range ids {
26-
res = append(res, string(id))
24+
res = make([]string, len(ids))
25+
for i, id := range ids {
26+
res[i] = string(id)
2727
}
2828
return res
2929
}

p2p/host/autonat/dialpolicy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func (d *dialPolicy) skipDial(addr ma.Multiaddr) bool {
5858
// public addresses in the list.
5959
func (d *dialPolicy) skipPeer(addrs []ma.Multiaddr) bool {
6060
localAddrs := d.host.Addrs()
61-
localHosts := make([]net.IP, 0)
61+
localHosts := make([]net.IP, 0, len(localAddrs))
6262
for _, lAddr := range localAddrs {
6363
if _, err := lAddr.ValueForProtocol(ma.P_CIRCUIT); err != nil && manet.IsPublicAddr(lAddr) {
6464
lIP, err := manet.ToIP(lAddr)

p2p/host/autorelay/addrsplosion.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import (
1313
// best address for the relay. Instead we should rely on the addresses provided by the
1414
// relay in response to the reservation request.
1515
func cleanupAddressSet(addrs []ma.Multiaddr) []ma.Multiaddr {
16-
var public, private []ma.Multiaddr
16+
public := make([]ma.Multiaddr, 0, len(addrs))
17+
private := make([]ma.Multiaddr, 0, len(addrs))
1718

1819
for _, a := range addrs {
1920
if isRelayAddr(a) {

p2p/host/basic/addrs_manager.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,12 @@ func areAddrsDifferent(prev, current []ma.Multiaddr) bool {
704704
// diffAddrs diffs prev and current addrs and returns added, maintained, and removed addrs.
705705
// Both prev and current are expected to be sorted using ma.Compare()
706706
func diffAddrs(prev, current []ma.Multiaddr) (added, maintained, removed []ma.Multiaddr) {
707+
added = make([]ma.Multiaddr, 0, len(current))
708+
removed = make([]ma.Multiaddr, 0, len(prev))
709+
710+
minLen := min(len(current), len(prev))
711+
maintained = make([]ma.Multiaddr, 0, minLen)
712+
707713
i, j := 0, 0
708714
for i < len(prev) && j < len(current) {
709715
cmp := prev[i].Compare(current[j])

p2p/net/swarm/dial_ranker.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ func NoDelayDialRanker(addrs []ma.Multiaddr) []network.AddrDelay {
7979
//
8080
// We dial lowest ports first as they are more likely to be the listen port.
8181
func DefaultDialRanker(addrs []ma.Multiaddr) []network.AddrDelay {
82+
totalAddrs := len(addrs)
8283
relay, addrs := filterAddrs(addrs, isRelayAddr)
8384
pvt, addrs := filterAddrs(addrs, manet.IsPrivateAddr)
8485
public, addrs := filterAddrs(addrs, func(a ma.Multiaddr) bool { return isProtocolAddr(a, ma.P_IP4) || isProtocolAddr(a, ma.P_IP6) })
@@ -89,7 +90,7 @@ func DefaultDialRanker(addrs []ma.Multiaddr) []network.AddrDelay {
8990
relayOffset = RelayDelay
9091
}
9192

92-
res := make([]network.AddrDelay, 0, len(addrs))
93+
res := make([]network.AddrDelay, 0, totalAddrs)
9394
res = append(res, getAddrDelay(pvt, PrivateTCPDelay, PrivateQUICDelay, PrivateOtherDelay, 0)...)
9495
res = append(res, getAddrDelay(public, PublicTCPDelay, PublicQUICDelay, PublicOtherDelay, 0)...)
9596
res = append(res, getAddrDelay(relay, PublicTCPDelay, PublicQUICDelay, PublicOtherDelay, relayOffset)...)

p2p/net/swarm/dial_worker.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,8 @@ loop:
208208
// If they have errored, record the error in pr. If they have succeeded,
209209
// respond with the connection.
210210
// If they are pending, add them to tojoin.
211-
// If we haven't seen any of the addresses before, add them to todial.
212-
var todial []ma.Multiaddr
213-
var tojoin []*addrDial
211+
todial := make([]ma.Multiaddr, 0, len(addrRanking))
212+
tojoin := make([]*addrDial, 0, len(addrRanking))
214213

215214
for _, adelay := range addrRanking {
216215
ad, ok := w.trackedDials[string(adelay.Addr.Bytes())]

p2p/net/swarm/swarm.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,6 @@ func (r ResolverFromMaDNS) ResolveDNSAddr(ctx context.Context, expectedPeerID pe
896896
if recursionLimit <= 0 {
897897
return []ma.Multiaddr{maddr}, nil
898898
}
899-
var resolved, toResolve []ma.Multiaddr
900899
addrs, err := r.Resolve(ctx, maddr)
901900
if err != nil {
902901
return nil, err
@@ -905,6 +904,10 @@ func (r ResolverFromMaDNS) ResolveDNSAddr(ctx context.Context, expectedPeerID pe
905904
addrs = addrs[:outputLimit]
906905
}
907906

907+
resolved := make([]ma.Multiaddr, 0, len(addrs))
908+
toResolve := make([]ma.Multiaddr, 0, len(addrs))
909+
910+
908911
for _, addr := range addrs {
909912
if startsWithDNSADDR(addr) {
910913
toResolve = append(toResolve, addr)

p2p/net/swarm/swarm_dial.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ type resolveErr struct {
352352

353353
func chainResolvers(ctx context.Context, addrs []ma.Multiaddr, outputLimit int, resolvers []resolver) ([]ma.Multiaddr, []resolveErr) {
354354
nextAddrs := make([]ma.Multiaddr, 0, len(addrs))
355-
errs := make([]resolveErr, 0)
355+
errs := make([]resolveErr, 0, len(addrs))
356356
for _, r := range resolvers {
357357
for _, a := range addrs {
358358
if !r.canResolve(a) {
@@ -388,7 +388,7 @@ func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) []ma.Multiad
388388
},
389389
}
390390

391-
var skipped []ma.Multiaddr
391+
skipped := make([]ma.Multiaddr, 0, len(pi.Addrs))
392392
skipResolver := resolver{
393393
canResolve: func(addr ma.Multiaddr) bool {
394394
tpt := s.TransportForDialing(addr)
@@ -486,7 +486,7 @@ var quicDraft29DialMatcher = mafmt.And(mafmt.IP, mafmt.Base(ma.P_UDP), mafmt.Bas
486486
// know are going to fail or for which we have a better alternative.
487487
func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) (goodAddrs []ma.Multiaddr, addrErrs []TransportError) {
488488
lisAddrs, _ := s.InterfaceListenAddresses()
489-
var ourAddrs []ma.Multiaddr
489+
ourAddrs := make([]ma.Multiaddr, 0, len(lisAddrs))
490490
for _, addr := range lisAddrs {
491491
// we're only sure about filtering out /ip4 and /ip6 addresses, so far
492492
ma.ForEach(addr, func(c ma.Component) bool {

p2p/protocol/identify/id.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ func (ids *idService) getSignedRecord(snapshot *identifySnapshot) []byte {
703703

704704
// diff takes two slices of strings (a and b) and computes which elements were added and removed in b
705705
func diff(a, b []protocol.ID) (added, removed []protocol.ID) {
706+
added = make([]protocol.ID, 0, len(b))
707+
removed = make([]protocol.ID, 0, len(a))
708+
706709
// This is O(n^2), but it's fine because the slices are small.
707710
for _, x := range b {
708711
var found bool

0 commit comments

Comments
 (0)