diff options
| author | Rui Ueyama <ruiu@google.com> | 2014-06-19 11:22:50 -0700 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2014-06-19 11:22:50 -0700 |
| commit | 1ca10de35d289346468a9c5b26475265c375eb95 (patch) | |
| tree | e0cfbb65d5e40cd99eb7931eb08789ec0b640fa6 /src/pkg/strings/replace.go | |
| parent | 57964db3cb2ec2f3cbb1011a17a8c71d9d2c5b07 (diff) | |
| download | go-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.go | 44 |
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 } |
