net: use bytes.Equal instead of bytesEqual

bytes.Equal is written in assembly and is slightly faster than the
current Go bytesEqual from the net package.

benchcmp:
benchmark                 old ns/op     new ns/op     delta
BenchmarkIPCompare4-8     7.74          7.01          -9.43%
BenchmarkIPCompare6-8     8.47          6.86          -19.01%

Change-Id: I2a7ad35867489b46f0943aef5776a2fe1b46e2df
Reviewed-on: https://go-review.googlesource.com/36850
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Erik Dubbelboer 2017-02-09 12:54:25 +08:00 committed by Brad Fitzpatrick
parent 61bf0d1c40
commit 39fcf8bf0e
2 changed files with 35 additions and 11 deletions

View File

@ -12,6 +12,8 @@
package net
import _ "unsafe" // for go:linkname
// IP address lengths (bytes).
const (
IPv4len = 4
@ -381,17 +383,9 @@ func (ip IP) Equal(x IP) bool {
return false
}
func bytesEqual(x, y []byte) bool {
if len(x) != len(y) {
return false
}
for i, b := range x {
if y[i] != b {
return false
}
}
return true
}
// bytes.Equal is implemented in runtime/asm_$goarch.s
//go:linkname bytesEqual bytes.Equal
func bytesEqual(x, y []byte) bool
func (ip IP) matchAddrFamily(x IP) bool {
return ip.To4() != nil && x.To4() != nil || ip.To16() != nil && ip.To4() == nil && x.To16() != nil && x.To4() == nil

View File

@ -6,6 +6,7 @@ package net
import (
"bytes"
"math/rand"
"reflect"
"runtime"
"testing"
@ -645,3 +646,32 @@ func TestIPAddrScope(t *testing.T) {
}
}
}
func BenchmarkIPEqual(b *testing.B) {
b.Run("IPv4", func(b *testing.B) {
benchmarkIPEqual(b, IPv4len)
})
b.Run("IPv6", func(b *testing.B) {
benchmarkIPEqual(b, IPv6len)
})
}
func benchmarkIPEqual(b *testing.B, size int) {
ips := make([]IP, 1000)
for i := range ips {
ips[i] = make(IP, size)
rand.Read(ips[i])
}
// Half of the N are equal.
for i := 0; i < b.N/2; i++ {
x := ips[i%len(ips)]
y := ips[i%len(ips)]
x.Equal(y)
}
// The other half are not equal.
for i := 0; i < b.N/2; i++ {
x := ips[i%len(ips)]
y := ips[(i+1)%len(ips)]
x.Equal(y)
}
}