]> Cypherpunks repositories - gostls13.git/commitdiff
strings: reduce allocation for byteReplacer
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 16 Aug 2022 03:59:05 +0000 (10:59 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 19 Aug 2022 16:32:49 +0000 (16:32 +0000)
Though it increases the execution time, the function is already quite
fast for most users, the allocation is much more important.

name                       old time/op    new time/op    delta
ByteReplacerWriteString-8    1.23µs ± 0%    2.16µs ± 1%   +75.31%  (p=0.000 n=10+10)

name                       old alloc/op   new alloc/op   delta
ByteReplacerWriteString-8    2.69kB ± 0%    0.00kB       -100.00%  (p=0.000 n=10+10)

name                       old allocs/op  new allocs/op  delta
ByteReplacerWriteString-8      1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)

Change-Id: I6a36df5fcb8e11ef27e6c7b252aa88e869592f3c
Reviewed-on: https://go-review.googlesource.com/c/go/+/424136
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Joedian Reid <joedian@golang.org>
src/strings/replace.go

index 73bc78a07ec394d1f36f3d2a949ddf9c1bef4996..f504fb48dfbdd90918327b60fb7980e745632574 100644 (file)
@@ -455,21 +455,30 @@ func (r *byteReplacer) Replace(s string) string {
 }
 
 func (r *byteReplacer) WriteString(w io.Writer, s string) (n int, err error) {
-       // TODO(bradfitz): use io.WriteString with slices of s, avoiding allocation.
-       bufsize := 32 << 10
-       if len(s) < bufsize {
-               bufsize = len(s)
-       }
-       buf := make([]byte, bufsize)
-
-       for len(s) > 0 {
-               ncopy := copy(buf, s)
-               s = s[ncopy:]
-               for i, b := range buf[:ncopy] {
-                       buf[i] = r[b]
+       sw := getStringWriter(w)
+       last := 0
+       for i := 0; i < len(s); i++ {
+               b := s[i]
+               if r[b] == b {
+                       continue
                }
-               wn, err := w.Write(buf[:ncopy])
-               n += wn
+               if last != i {
+                       wn, err := sw.WriteString(s[last:i])
+                       n += wn
+                       if err != nil {
+                               return n, err
+                       }
+               }
+               last = i + 1
+               nw, err := w.Write(r[b : int(b)+1])
+               n += nw
+               if err != nil {
+                       return n, err
+               }
+       }
+       if last != len(s) {
+               nw, err := sw.WriteString(s[last:])
+               n += nw
                if err != nil {
                        return n, err
                }