]> Cypherpunks repositories - gostls13.git/commitdiff
net/url: improve URL.String performance
authorKoya IWAMURA <kiwamura0314@gmail.com>
Tue, 23 Apr 2024 16:16:08 +0000 (01:16 +0900)
committerGopher Robot <gobot@golang.org>
Mon, 29 Apr 2024 13:58:27 +0000 (13:58 +0000)
URL.String performs memory allocation many times, but it can improve
performance by allocating memory that it clearly knows it needs.
This CL achieves 24.6% speedup, 18.3% memory reduction, and 46.7% fewer memory
allocations on existing benchmarks.

          │ string_old.txt │           string_new2.txt           │
          │     sec/op     │   sec/op     vs base                │
String-16      3.622µ ± 5%   2.730µ ± 2%  -24.63% (p=0.000 n=10)

          │ string_old.txt │           string_new2.txt            │
          │      B/op      │     B/op      vs base                │
String-16     1.406Ki ± 0%   1.148Ki ± 0%  -18.33% (p=0.000 n=10)

          │ string_old.txt │          string_new2.txt           │
          │   allocs/op    │ allocs/op   vs base                │
String-16       60.00 ± 0%   32.00 ± 0%  -46.67% (p=0.000 n=10)

Change-Id: I70199be952eddc44134945077e52740e8921088f
Reviewed-on: https://go-review.googlesource.com/c/go/+/581155
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Joedian Reid <joedian@google.com>
src/net/url/url.go

index f362958edd72a7f475a207eeb2f0ae9c4f0b8d80..7cd6913ad7e3f794cff301ae1ca709c335023add 100644 (file)
@@ -814,6 +814,22 @@ func validOptionalPort(port string) bool {
 //   - if u.Fragment is empty, #fragment is omitted.
 func (u *URL) String() string {
        var buf strings.Builder
+
+       n := len(u.Scheme)
+       if u.Opaque != "" {
+               n += len(u.Opaque)
+       } else {
+               if !u.OmitHost && (u.Scheme != "" || u.Host != "" || u.User != nil) {
+                       username := u.User.Username()
+                       password, _ := u.User.Password()
+                       n += len(username) + len(password) + len(u.Host)
+               }
+               n += len(u.Path)
+       }
+       n += len(u.RawQuery) + len(u.RawFragment)
+       n += len(":" + "//" + "//" + ":" + "@" + "/" + "./" + "?" + "#")
+       buf.Grow(n)
+
        if u.Scheme != "" {
                buf.WriteString(u.Scheme)
                buf.WriteByte(':')