strings: make IndexRune faster

re-implement IndexRune by Index which is well optimized to get
performance gain.

name                   old time/op  new time/op  delta
IndexRune-4            30.2ns ± 1%  28.3ns ± 1%   -6.22%  (p=0.000 n=20+19)
IndexRuneLongString-4   156ns ± 1%    49ns ± 1%  -68.72%  (p=0.000 n=19+19)
IndexRuneFastPath-4    10.6ns ± 2%  10.0ns ± 1%   -6.30%  (p=0.000 n=18+18)

Change-Id: Ie663b8f7860ca51892dd4be182fca3caa5f8ae61
Reviewed-on: https://go-review.googlesource.com/28546
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Hiroshi Ioka 2016-09-06 20:23:40 +09:00 committed by Brad Fitzpatrick
parent a4bdd64555
commit 8737dac1f2
3 changed files with 30 additions and 9 deletions

View file

@ -244,6 +244,20 @@ func TestIndexRune(t *testing.T) {
t.Errorf("IndexRune(%q,%d)= %v; want %v", test.s, test.rune, actual, test.out)
}
}
haystack := "test世界"
allocs := testing.AllocsPerRun(1000, func() {
if i := IndexRune(haystack, 's'); i != 2 {
t.Fatalf("'s' at %d; want 2", i)
}
if i := IndexRune(haystack, '世'); i != 4 {
t.Fatalf("'世' at %d; want 4", i)
}
})
if allocs != 0 {
t.Errorf(`expected no allocations, got %f`, allocs)
}
}
const benchmarkString = "some_text=some☺value"
@ -257,6 +271,17 @@ func BenchmarkIndexRune(b *testing.B) {
}
}
var benchmarkLongString = Repeat(" ", 100) + benchmarkString
func BenchmarkIndexRuneLongString(b *testing.B) {
if got := IndexRune(benchmarkLongString, '☺'); got != 114 {
b.Fatalf("wrong index: expected 114, got=%d", got)
}
for i := 0; i < b.N; i++ {
IndexRune(benchmarkLongString, '☺')
}
}
func BenchmarkIndexRuneFastPath(b *testing.B) {
if got := IndexRune(benchmarkString, 'v'); got != 17 {
b.Fatalf("wrong index: expected 17, got=%d", got)