1
0
mirror of https://github.com/golang/go synced 2024-11-24 09:30:07 -07:00

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
This commit is contained in:
Rui Ueyama 2014-06-20 12:18:33 -07:00
parent 22d46d53ea
commit 382c461a89
2 changed files with 16 additions and 6 deletions

View File

@ -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,10 +463,8 @@ 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]
}
}
wn, err := w.Write(buf[:ncopy])
n += wn
if err != nil {

View File

@ -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)