package net
+import _ "unsafe" // for go:linkname
+
// IP address lengths (bytes).
const (
IPv4len = 4
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
import (
"bytes"
+ "math/rand"
"reflect"
"runtime"
"testing"
}
}
}
+
+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)
+ }
+}