From 108021c195c6f43b07c437242bf39614e06b3df4 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Tue, 16 Aug 2022 10:59:05 +0700 Subject: [PATCH] strings: reduce allocation for byteReplacer MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Ian Lance Taylor TryBot-Result: Gopher Robot Reviewed-by: Joedian Reid --- src/strings/replace.go | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/strings/replace.go b/src/strings/replace.go index 73bc78a07e..f504fb48df 100644 --- a/src/strings/replace.go +++ b/src/strings/replace.go @@ -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 } -- 2.48.1