aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/strings/replace.go
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-06-19 11:22:50 -0700
committerRui Ueyama <ruiu@google.com>2014-06-19 11:22:50 -0700
commit1ca10de35d289346468a9c5b26475265c375eb95 (patch)
treee0cfbb65d5e40cd99eb7931eb08789ec0b640fa6 /src/pkg/strings/replace.go
parent57964db3cb2ec2f3cbb1011a17a8c71d9d2c5b07 (diff)
downloadgo-1ca10de35d289346468a9c5b26475265c375eb95.tar.xz
strings: reduce allocation in byteStringReplacer.WriteString
Use WriteString instead of allocating a byte slice as a buffer. This was a TODO. benchmark old ns/op new ns/op delta BenchmarkWriteString 40139 19991 -50.20% LGTM=bradfitz R=golang-codereviews, bradfitz CC=golang-codereviews https://golang.org/cl/107190044
Diffstat (limited to 'src/pkg/strings/replace.go')
-rw-r--r--src/pkg/strings/replace.go44
1 files changed, 14 insertions, 30 deletions
diff --git a/src/pkg/strings/replace.go b/src/pkg/strings/replace.go
index 16889bac99..c661265613 100644
--- a/src/pkg/strings/replace.go
+++ b/src/pkg/strings/replace.go
@@ -511,48 +511,32 @@ func (r *byteStringReplacer) Replace(s string) string {
return string(buf)
}
-// WriteString maintains one buffer that's at most 32KB. The bytes in
-// s are enumerated and the buffer is filled. If it reaches its
-// capacity or a byte has a replacement, the buffer is flushed to w.
func (r *byteStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
- // TODO(bradfitz): use io.WriteString with slices of s instead.
- bufsize := 32 << 10
- if len(s) < bufsize {
- bufsize = len(s)
- }
- buf := make([]byte, bufsize)
- bi := buf[:0]
-
+ sw := getStringWriter(w)
+ last := 0
for i := 0; i < len(s); i++ {
b := s[i]
- var new []byte
- if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
- new = r.new[b]
- } else {
- bi = append(bi, b)
- }
- if len(bi) == cap(bi) || (len(bi) > 0 && len(new) > 0) {
- nw, err := w.Write(bi)
- n += nw
- if err != nil {
- return n, err
- }
- bi = buf[:0]
+ if r.old[b>>5]&uint32(1<<(b&31)) == 0 {
+ continue
}
- if len(new) > 0 {
- nw, err := w.Write(new)
+ if last != i {
+ nw, err := sw.WriteString(s[last:i])
n += nw
if err != nil {
return n, err
}
}
- }
- if len(bi) > 0 {
- nw, err := w.Write(bi)
+ last = i + 1
+ nw, err := w.Write(r.new[b])
n += nw
if err != nil {
return n, err
}
}
- return n, nil
+ if last != len(s) {
+ var nw int
+ nw, err = sw.WriteString(s[last:])
+ n += nw
+ }
+ return
}