]> Cypherpunks repositories - gostls13.git/commitdiff
strings: add IndexRune tests, ASCII fast path
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 8 Mar 2011 17:41:12 +0000 (09:41 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 8 Mar 2011 17:41:12 +0000 (09:41 -0800)
$ 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

src/pkg/strings/strings.go
src/pkg/strings/strings_test.go

index 98a0d5731ec3d9f547e1f8e7e6206baa990fa718..5f009e54859146fb2d17345686758006d496277b 100644 (file)
@@ -119,9 +119,19 @@ func LastIndex(s, sep string) int {
 // IndexRune returns the index of the first instance of the Unicode code point
 // rune, or -1 if rune is not present in s.
 func IndexRune(s string, rune int) int {
-       for i, c := range s {
-               if c == rune {
-                       return i
+       switch {
+       case rune < 0x80:
+               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
index 734fdd33daa71f1ca90e5b6527c3a03ebb6120cf..b218c7a2ab6a6a844806bdc441d8b6042feb472d 100644 (file)
@@ -6,6 +6,7 @@ package strings_test
 
 import (
        "os"
+       "strconv"
        . "strings"
        "testing"
        "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 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 {
        s string
        n int