mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
a4bdd64555
commit
8737dac1f2
3 changed files with 30 additions and 9 deletions
|
|
@ -176,17 +176,11 @@ func LastIndex(s, sep string) int {
|
||||||
// IndexRune returns the index of the first instance of the Unicode code point
|
// IndexRune returns the index of the first instance of the Unicode code point
|
||||||
// r, or -1 if rune is not present in s.
|
// r, or -1 if rune is not present in s.
|
||||||
func IndexRune(s string, r rune) int {
|
func IndexRune(s string, r rune) int {
|
||||||
switch {
|
if r < utf8.RuneSelf {
|
||||||
case r < utf8.RuneSelf:
|
|
||||||
return IndexByte(s, byte(r))
|
return IndexByte(s, byte(r))
|
||||||
default:
|
|
||||||
for i, c := range s {
|
|
||||||
if c == r {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1
|
|
||||||
|
return Index(s, string(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexAny returns the index of the first instance of any Unicode code point
|
// IndexAny returns the index of the first instance of any Unicode code point
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package strings
|
package strings
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
// indexShortStr returns the index of the first instance of c in s, or -1 if c is not present in s.
|
// indexShortStr returns the index of the first instance of c in s, or -1 if c is not present in s.
|
||||||
// indexShortStr requires 2 <= len(c) <= shortStringLen
|
// indexShortStr requires 2 <= len(c) <= shortStringLen
|
||||||
func indexShortStr(s, c string) int // ../runtime/asm_$GOARCH.s
|
func indexShortStr(s, c string) int // ../runtime/asm_$GOARCH.s
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,20 @@ func TestIndexRune(t *testing.T) {
|
||||||
t.Errorf("IndexRune(%q,%d)= %v; want %v", test.s, test.rune, actual, test.out)
|
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"
|
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) {
|
func BenchmarkIndexRuneFastPath(b *testing.B) {
|
||||||
if got := IndexRune(benchmarkString, 'v'); got != 17 {
|
if got := IndexRune(benchmarkString, 'v'); got != 17 {
|
||||||
b.Fatalf("wrong index: expected 17, got=%d", got)
|
b.Fatalf("wrong index: expected 17, got=%d", got)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue