mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
strings: add IndexRune tests, ASCII fast path
$ gotest -test.v -test.run=IndexRune -test.bench=.* === RUN strings_test.TestIndexRune --- PASS: strings_test.TestIndexRune (0.0 seconds) PASS strings_test.BenchmarkIndexRune 20000000 105 ns/op strings_test.BenchmarkIndexByte 50000000 48 ns/op R=rsc, dsymonds CC=golang-dev https://golang.org/cl/4267050
This commit is contained in:
parent
87aa93457e
commit
145108ed36
2 changed files with 53 additions and 3 deletions
|
|
@ -119,9 +119,19 @@ 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
|
||||||
// rune, or -1 if rune is not present in s.
|
// rune, or -1 if rune is not present in s.
|
||||||
func IndexRune(s string, rune int) int {
|
func IndexRune(s string, rune int) int {
|
||||||
for i, c := range s {
|
switch {
|
||||||
if c == rune {
|
case rune < 0x80:
|
||||||
return i
|
b := byte(rune)
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] == b {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
for i, c := range s {
|
||||||
|
if c == rune {
|
||||||
|
return i
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package strings_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
. "strings"
|
. "strings"
|
||||||
"testing"
|
"testing"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
@ -116,6 +117,45 @@ func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", l
|
||||||
func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
|
func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
|
||||||
func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) }
|
func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) }
|
||||||
|
|
||||||
|
type IndexRuneTest struct {
|
||||||
|
s string
|
||||||
|
rune int
|
||||||
|
out int
|
||||||
|
}
|
||||||
|
|
||||||
|
var indexRuneTests = []IndexRuneTest{
|
||||||
|
{"a A x", 'A', 2},
|
||||||
|
{"some_text=some_value", '=', 9},
|
||||||
|
{"☺a", 'a', 3},
|
||||||
|
{"a☻☺b", '☺', 4},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIndexRune(t *testing.T) {
|
||||||
|
for _, test := range indexRuneTests {
|
||||||
|
if actual := IndexRune(test.s, test.rune); actual != test.out {
|
||||||
|
t.Errorf("IndexRune(%q,%d)= %v; want %v", test.s, test.rune, actual, test.out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkIndexRune(b *testing.B) {
|
||||||
|
if got := IndexRune("some_text=some☺value", '☺'); got != 14 {
|
||||||
|
panic("wrong index: got=" + strconv.Itoa(got))
|
||||||
|
}
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
IndexRune("some_text=some☺value", '☺')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkIndexByte(b *testing.B) {
|
||||||
|
if got := IndexRune("some_text=some☺value", 'v'); got != 17 {
|
||||||
|
panic("wrong index: got=" + strconv.Itoa(got))
|
||||||
|
}
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
IndexRune("some_text=some☺value", 'v')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ExplodeTest struct {
|
type ExplodeTest struct {
|
||||||
s string
|
s string
|
||||||
n int
|
n int
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue