From: Rui Ueyama Date: Fri, 20 Jun 2014 19:18:33 +0000 (-0700) Subject: strings: speed up byteReplacer.Replace X-Git-Tag: go1.4beta1~1250 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=382c461a89bf2ee1ab91ba9c193f5cb7d257246c;p=gostls13.git strings: speed up byteReplacer.Replace benchmark old ns/op new ns/op delta BenchmarkByteReplacerWriteString 7359 3661 -50.25% LGTM=dave R=golang-codereviews, dave CC=golang-codereviews https://golang.org/cl/102550043 --- diff --git a/src/pkg/strings/replace.go b/src/pkg/strings/replace.go index 03fb6b249d..cb9d7b1fa4 100644 --- a/src/pkg/strings/replace.go +++ b/src/pkg/strings/replace.go @@ -53,6 +53,9 @@ func NewReplacer(oldnew ...string) *Replacer { if allNewBytes { bb := &byteReplacer{} + for i := range bb.new { + bb.new[i] = byte(i) + } for i := 0; i < len(oldnew); i += 2 { o, n := oldnew[i][0], oldnew[i+1][0] if bb.old.isSet(o) { @@ -426,8 +429,8 @@ type byteReplacer struct { // old has a bit set for each old byte that should be replaced. old byteBitmap - // replacement byte, indexed by old byte. only valid if - // corresponding old bit is set. + // replacement byte, indexed by old byte. old byte and new + // byte are the same if corresponding old bit is not set. new [256]byte } @@ -460,9 +463,7 @@ func (r *byteReplacer) WriteString(w io.Writer, s string) (n int, err error) { ncopy := copy(buf, s[:]) s = s[ncopy:] for i, b := range buf[:ncopy] { - if r.old.isSet(b) { - buf[i] = r.new[b] - } + buf[i] = r.new[b] } wn, err := w.Write(buf[:ncopy]) n += wn diff --git a/src/pkg/strings/replace_test.go b/src/pkg/strings/replace_test.go index ca57f08251..2cb318b69d 100644 --- a/src/pkg/strings/replace_test.go +++ b/src/pkg/strings/replace_test.go @@ -480,7 +480,7 @@ func BenchmarkHTMLEscapeOld(b *testing.B) { } } -func BenchmarkWriteString(b *testing.B) { +func BenchmarkByteStringReplacerWriteString(b *testing.B) { str := Repeat("I <3 to escape HTML & other text too.", 100) buf := new(bytes.Buffer) for i := 0; i < b.N; i++ { @@ -489,6 +489,15 @@ func BenchmarkWriteString(b *testing.B) { } } +func BenchmarkByteReplacerWriteString(b *testing.B) { + str := Repeat("abcdefghijklmnopqrstuvwxyz", 100) + buf := new(bytes.Buffer) + for i := 0; i < b.N; i++ { + capitalLetters.WriteString(buf, str) + buf.Reset() + } +} + // BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces. func BenchmarkByteByteReplaces(b *testing.B) { str := Repeat("a", 100) + Repeat("b", 100)