]> Cypherpunks repositories - gostls13.git/commitdiff
net/netip: further optimize AddrPort.String
authorTobias Klauser <tklauser@distanz.ch>
Wed, 24 Jan 2024 21:13:17 +0000 (22:13 +0100)
committerGopher Robot <gobot@golang.org>
Wed, 24 Jan 2024 22:25:08 +0000 (22:25 +0000)
name                          old time/op    new time/op    delta
AddrPortString/v4-8             29.0ns ± 0%    28.2ns ± 1%   -2.74%  (p=0.000 n=8+9)
AddrPortString/v6-8             96.0ns ± 0%    65.1ns ± 0%  -32.22%  (p=0.000 n=10+10)
AddrPortString/v6_ellipsis-8    98.5ns ± 0%    68.0ns ± 1%  -30.95%  (p=0.000 n=10+10)
AddrPortString/v6_v4-8          71.8ns ± 1%    33.9ns ± 0%  -52.88%  (p=0.000 n=10+10)
AddrPortString/v6_zone-8        98.5ns ± 0%    68.6ns ± 0%  -30.35%  (p=0.000 n=8+9)

name                          old alloc/op   new alloc/op   delta
AddrPortString/v4-8              24.0B ± 0%     24.0B ± 0%     ~     (all equal)
AddrPortString/v6-8              96.0B ± 0%     48.0B ± 0%  -50.00%  (p=0.000 n=10+10)
AddrPortString/v6_ellipsis-8     56.0B ± 0%     32.0B ± 0%  -42.86%  (p=0.000 n=10+10)
AddrPortString/v6_v4-8           56.0B ± 0%     32.0B ± 0%  -42.86%  (p=0.000 n=10+10)
AddrPortString/v6_zone-8         56.0B ± 0%     32.0B ± 0%  -42.86%  (p=0.000 n=10+10)

name                          old allocs/op  new allocs/op  delta
AddrPortString/v4-8               1.00 ± 0%      1.00 ± 0%     ~     (all equal)
AddrPortString/v6-8               2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
AddrPortString/v6_ellipsis-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
AddrPortString/v6_v4-8            2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
AddrPortString/v6_zone-8          2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)

Change-Id: Iae077c5c80db3d236d7ec9a02d20a96b0e3a96e3
Reviewed-on: https://go-review.googlesource.com/c/go/+/557775
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/net/netip/netip.go

index 7a189e8e16f4fb893557b9c08711495271ee42e5..156f01e11e3a0691f2495e2749ff01b8edfb9688 100644 (file)
@@ -847,6 +847,16 @@ func (ip Addr) appendTo4(ret []byte) []byte {
        return ret
 }
 
+func (ip Addr) appendTo4In6(ret []byte) []byte {
+       ret = append(ret, "::ffff:"...)
+       ret = ip.Unmap().appendTo4(ret)
+       if ip.z != z6noz {
+               ret = append(ret, '%')
+               ret = append(ret, ip.Zone()...)
+       }
+       return ret
+}
+
 // string6 formats ip in IPv6 textual representation. It follows the
 // guidelines in section 4 of RFC 5952
 // (https://tools.ietf.org/html/rfc5952#section-4): no unnecessary
@@ -942,13 +952,7 @@ func (ip Addr) MarshalText() ([]byte, error) {
                max := len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
                b := make([]byte, 0, max)
                if ip.Is4In6() {
-                       b = append(b, "::ffff:"...)
-                       b = ip.Unmap().appendTo4(b)
-                       if z := ip.Zone(); z != "" {
-                               b = append(b, '%')
-                               b = append(b, z...)
-                       }
-                       return b, nil
+                       return ip.appendTo4In6(b), nil
                }
                return ip.appendTo6(b), nil
        }
@@ -1114,20 +1118,31 @@ func (p AddrPort) Compare(p2 AddrPort) int {
 }
 
 func (p AddrPort) String() string {
+       var b []byte
        switch p.ip.z {
        case z0:
                return "invalid AddrPort"
        case z4:
                const max = len("255.255.255.255:65535")
-               buf := make([]byte, 0, max)
-               buf = p.ip.appendTo4(buf)
-               buf = append(buf, ':')
-               buf = strconv.AppendUint(buf, uint64(p.port), 10)
-               return string(buf)
+               b = make([]byte, 0, max)
+               b = p.ip.appendTo4(b)
        default:
-               // TODO: this could be more efficient allocation-wise:
-               return "[" + p.ip.String() + "]:" + itoa.Uitoa(uint(p.port))
+               if p.ip.Is4In6() {
+                       const max = len("[::ffff:255.255.255.255%enp5s0]:65535")
+                       b = make([]byte, 0, max)
+                       b = append(b, '[')
+                       b = p.ip.appendTo4In6(b)
+               } else {
+                       const max = len("[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0]:65535")
+                       b = make([]byte, 0, max)
+                       b = append(b, '[')
+                       b = p.ip.appendTo6(b)
+               }
+               b = append(b, ']')
        }
+       b = append(b, ':')
+       b = strconv.AppendUint(b, uint64(p.port), 10)
+       return string(b)
 }
 
 // AppendTo appends a text encoding of p,
@@ -1140,15 +1155,10 @@ func (p AddrPort) AppendTo(b []byte) []byte {
        case z4:
                b = p.ip.appendTo4(b)
        default:
+               b = append(b, '[')
                if p.ip.Is4In6() {
-                       b = append(b, "[::ffff:"...)
-                       b = p.ip.Unmap().appendTo4(b)
-                       if z := p.ip.Zone(); z != "" {
-                               b = append(b, '%')
-                               b = append(b, z...)
-                       }
+                       b = p.ip.appendTo4In6(b)
                } else {
-                       b = append(b, '[')
                        b = p.ip.appendTo6(b)
                }
                b = append(b, ']')