2009-06-04 14:41:31 -07:00
|
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
2009-08-12 13:18:37 -07:00
|
|
|
|
package bytes_test
|
2009-06-04 14:41:31 -07:00
|
|
|
|
|
|
|
|
|
|
import (
|
2009-12-15 15:33:31 -08:00
|
|
|
|
. "bytes"
|
2016-05-26 10:54:25 +02:00
|
|
|
|
"fmt"
|
2025-03-20 20:42:05 +00:00
|
|
|
|
"internal/asan"
|
2016-09-14 18:03:26 +00:00
|
|
|
|
"internal/testenv"
|
2024-08-09 07:33:36 +00:00
|
|
|
|
"iter"
|
2022-04-05 20:28:16 +00:00
|
|
|
|
"math"
|
2012-09-18 15:02:08 -04:00
|
|
|
|
"math/rand"
|
2024-07-24 10:32:22 +00:00
|
|
|
|
"slices"
|
2016-09-14 18:03:26 +00:00
|
|
|
|
"strings"
|
2009-12-15 15:33:31 -08:00
|
|
|
|
"testing"
|
|
|
|
|
|
"unicode"
|
2011-11-08 15:40:58 -08:00
|
|
|
|
"unicode/utf8"
|
2021-10-31 10:04:03 +01:00
|
|
|
|
"unsafe"
|
2009-06-04 14:41:31 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
2013-01-07 10:48:06 +11:00
|
|
|
|
func sliceOfString(s [][]byte) []string {
|
|
|
|
|
|
result := make([]string, len(s))
|
|
|
|
|
|
for i, v := range s {
|
|
|
|
|
|
result[i] = string(v)
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
2009-12-15 15:33:31 -08:00
|
|
|
|
return result
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-09 07:33:36 +00:00
|
|
|
|
func collect(t *testing.T, seq iter.Seq[[]byte]) [][]byte {
|
|
|
|
|
|
out := slices.Collect(seq)
|
|
|
|
|
|
out1 := slices.Collect(seq)
|
|
|
|
|
|
if !slices.Equal(sliceOfString(out), sliceOfString(out1)) {
|
|
|
|
|
|
t.Fatalf("inconsistent seq:\n%s\n%s", out, out1)
|
|
|
|
|
|
}
|
|
|
|
|
|
return out
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type LinesTest struct {
|
|
|
|
|
|
a string
|
|
|
|
|
|
b []string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var linesTests = []LinesTest{
|
|
|
|
|
|
{a: "abc\nabc\n", b: []string{"abc\n", "abc\n"}},
|
|
|
|
|
|
{a: "abc\r\nabc", b: []string{"abc\r\n", "abc"}},
|
|
|
|
|
|
{a: "abc\r\n", b: []string{"abc\r\n"}},
|
|
|
|
|
|
{a: "\nabc", b: []string{"\n", "abc"}},
|
|
|
|
|
|
{a: "\nabc\n\n", b: []string{"\n", "abc\n", "\n"}},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestLines(t *testing.T) {
|
|
|
|
|
|
for _, s := range linesTests {
|
|
|
|
|
|
result := sliceOfString(slices.Collect(Lines([]byte(s.a))))
|
|
|
|
|
|
if !slices.Equal(result, s.b) {
|
|
|
|
|
|
t.Errorf(`slices.Collect(Lines(%q)) = %q; want %q`, s.a, result, s.b)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-06-04 14:41:31 -07:00
|
|
|
|
// For ease of reading, the test cases use strings that are converted to byte
|
2013-01-07 10:48:06 +11:00
|
|
|
|
// slices before invoking the functions.
|
2009-06-04 14:41:31 -07:00
|
|
|
|
|
|
|
|
|
|
var abcd = "abcd"
|
|
|
|
|
|
var faces = "☺☻☹"
|
|
|
|
|
|
var commas = "1,2,3,4"
|
|
|
|
|
|
var dots = "1....2....3....4"
|
|
|
|
|
|
|
2009-11-18 19:23:08 -08:00
|
|
|
|
type BinOpTest struct {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
a string
|
|
|
|
|
|
b string
|
|
|
|
|
|
i int
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
2009-10-08 15:14:54 -07:00
|
|
|
|
|
2013-05-14 16:05:51 -07:00
|
|
|
|
func TestEqual(t *testing.T) {
|
2019-04-22 14:39:55 -07:00
|
|
|
|
// Run the tests and check for allocation at the same time.
|
|
|
|
|
|
allocs := testing.AllocsPerRun(10, func() {
|
|
|
|
|
|
for _, tt := range compareTests {
|
|
|
|
|
|
eql := Equal(tt.a, tt.b)
|
|
|
|
|
|
if eql != (tt.i == 0) {
|
|
|
|
|
|
t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2019-04-22 14:39:55 -07:00
|
|
|
|
})
|
|
|
|
|
|
if allocs > 0 {
|
|
|
|
|
|
t.Errorf("Equal allocated %v times", allocs)
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-05-14 16:05:51 -07:00
|
|
|
|
func TestEqualExhaustive(t *testing.T) {
|
2013-04-02 16:26:15 -07:00
|
|
|
|
var size = 128
|
|
|
|
|
|
if testing.Short() {
|
|
|
|
|
|
size = 32
|
|
|
|
|
|
}
|
|
|
|
|
|
a := make([]byte, size)
|
|
|
|
|
|
b := make([]byte, size)
|
|
|
|
|
|
b_init := make([]byte, size)
|
|
|
|
|
|
// randomish but deterministic data
|
|
|
|
|
|
for i := 0; i < size; i++ {
|
|
|
|
|
|
a[i] = byte(17 * i)
|
|
|
|
|
|
b_init[i] = byte(23*i + 100)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for len := 0; len <= size; len++ {
|
|
|
|
|
|
for x := 0; x <= size-len; x++ {
|
|
|
|
|
|
for y := 0; y <= size-len; y++ {
|
|
|
|
|
|
copy(b, b_init)
|
|
|
|
|
|
copy(b[y:y+len], a[x:x+len])
|
|
|
|
|
|
if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) {
|
|
|
|
|
|
t.Errorf("Equal(%d, %d, %d) = false", len, x, y)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-03-01 23:21:55 +00:00
|
|
|
|
// make sure Equal returns false for minimally different strings. The data
|
2013-04-02 16:26:15 -07:00
|
|
|
|
// is all zeros except for a single one in one location.
|
|
|
|
|
|
func TestNotEqual(t *testing.T) {
|
|
|
|
|
|
var size = 128
|
|
|
|
|
|
if testing.Short() {
|
|
|
|
|
|
size = 32
|
|
|
|
|
|
}
|
|
|
|
|
|
a := make([]byte, size)
|
|
|
|
|
|
b := make([]byte, size)
|
|
|
|
|
|
|
|
|
|
|
|
for len := 0; len <= size; len++ {
|
|
|
|
|
|
for x := 0; x <= size-len; x++ {
|
|
|
|
|
|
for y := 0; y <= size-len; y++ {
|
|
|
|
|
|
for diffpos := x; diffpos < x+len; diffpos++ {
|
|
|
|
|
|
a[diffpos] = 1
|
|
|
|
|
|
if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) {
|
|
|
|
|
|
t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos)
|
|
|
|
|
|
}
|
|
|
|
|
|
a[diffpos] = 0
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-03-26 13:05:04 -07:00
|
|
|
|
var indexTests = []BinOpTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", "", 0},
|
|
|
|
|
|
{"", "a", -1},
|
|
|
|
|
|
{"", "foo", -1},
|
|
|
|
|
|
{"fo", "foo", -1},
|
2013-09-11 21:20:15 +10:00
|
|
|
|
{"foo", "baz", -1},
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"foo", "foo", 0},
|
|
|
|
|
|
{"oofofoofooo", "f", 2},
|
|
|
|
|
|
{"oofofoofooo", "foo", 4},
|
|
|
|
|
|
{"barfoobarfoo", "foo", 3},
|
|
|
|
|
|
{"foo", "", 0},
|
|
|
|
|
|
{"foo", "o", 1},
|
|
|
|
|
|
{"abcABCabc", "A", 3},
|
2010-03-26 13:05:04 -07:00
|
|
|
|
// cases with one byte strings - test IndexByte and special case in Index()
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", "a", -1},
|
|
|
|
|
|
{"x", "a", -1},
|
|
|
|
|
|
{"x", "x", 0},
|
|
|
|
|
|
{"abc", "a", 0},
|
|
|
|
|
|
{"abc", "b", 1},
|
|
|
|
|
|
{"abc", "c", 2},
|
|
|
|
|
|
{"abc", "x", -1},
|
2010-11-08 17:33:53 -08:00
|
|
|
|
{"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33},
|
2022-01-10 02:15:25 -06:00
|
|
|
|
{"fofofofooofoboo", "oo", 7},
|
|
|
|
|
|
{"fofofofofofoboo", "ob", 11},
|
|
|
|
|
|
{"fofofofofofoboo", "boo", 12},
|
|
|
|
|
|
{"fofofofofofoboo", "oboo", 11},
|
|
|
|
|
|
{"fofofofofoooboo", "fooo", 8},
|
|
|
|
|
|
{"fofofofofofoboo", "foboo", 10},
|
|
|
|
|
|
{"fofofofofofoboo", "fofob", 8},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffof", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffof", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofo", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofo", 13},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofoo", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofoo", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofoob", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofoob", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofooba", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofooba", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofoobar", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofoobar", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofoobarf", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofoobarf", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofoobarfo", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofoobarfo", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foffofoobarfoo", 13},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "foffofoobarfoo", 12},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "ofoffofoobarfoo", 12},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "ofoffofoobarfoo", 11},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "fofoffofoobarfoo", 11},
|
|
|
|
|
|
{"fofofofofofofoffofoobarfoo", "fofoffofoobarfoo", 10},
|
|
|
|
|
|
{"fofofofofoofofoffofoobarfoo", "foobars", -1},
|
2010-11-08 17:33:53 -08:00
|
|
|
|
{"foofyfoobarfoobar", "y", 4},
|
|
|
|
|
|
{"oooooooooooooooooooooo", "r", -1},
|
2017-11-04 10:19:53 -07:00
|
|
|
|
{"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22},
|
|
|
|
|
|
{"oxoxoxoxoxoxoxoxoxoxoxox", "oy", -1},
|
2019-11-21 14:38:25 +08:00
|
|
|
|
// test fallback to Rabin-Karp.
|
|
|
|
|
|
{"000000000000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000001", 5},
|
2023-11-02 00:18:59 -04:00
|
|
|
|
// test fallback to IndexRune
|
|
|
|
|
|
{"oxoxoxoxoxoxoxoxoxoxox☺", "☺", 22},
|
|
|
|
|
|
// invalid UTF-8 byte sequence (must be longer than bytealg.MaxBruteForce to
|
|
|
|
|
|
// test that we don't use IndexRune)
|
|
|
|
|
|
{"xx0123456789012345678901234567890123456789012345678901234567890120123456789012345678901234567890123456xxx\xed\x9f\xc0", "\xed\x9f\xc0", 105},
|
2009-11-18 19:23:08 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-03-26 13:05:04 -07:00
|
|
|
|
var lastIndexTests = []BinOpTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", "", 0},
|
|
|
|
|
|
{"", "a", -1},
|
|
|
|
|
|
{"", "foo", -1},
|
|
|
|
|
|
{"fo", "foo", -1},
|
|
|
|
|
|
{"foo", "foo", 0},
|
|
|
|
|
|
{"foo", "f", 0},
|
|
|
|
|
|
{"oofofoofooo", "f", 7},
|
|
|
|
|
|
{"oofofoofooo", "foo", 7},
|
|
|
|
|
|
{"barfoobarfoo", "foo", 9},
|
|
|
|
|
|
{"foo", "", 3},
|
|
|
|
|
|
{"foo", "o", 2},
|
|
|
|
|
|
{"abcABCabc", "A", 3},
|
|
|
|
|
|
{"abcABCabc", "a", 6},
|
2010-03-26 13:05:04 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var indexAnyTests = []BinOpTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", "", -1},
|
|
|
|
|
|
{"", "a", -1},
|
|
|
|
|
|
{"", "abc", -1},
|
|
|
|
|
|
{"a", "", -1},
|
|
|
|
|
|
{"a", "a", 0},
|
strings, bytes: improve IndexAny and LastIndexAny performance
For the case of a pattern containing multi-byte rune, the time complexity of the
previous algorithm is O(nm), and if both input arguments are long, the search
performance will be poor. This CL improves the searching performance for these
cases by using IndexRune, which is mainly implemented with IndexByte and Index.
As IndexByte and Index are specially optimized with some powerful instructions
for short patterns (an UTF8 rune is 1 to 4 bytes), so they can help to reduce the
runtime complexity of IndexAny and LastIndexAny.
Another optimization method is using hash table, however, the actual test results
show that using indexrune is better, and the space complexity is lower.
There are two fast paths in IndexAny and LastIndexAny for cases where the length
of the input arguements are 1, and their locations are not exactly the same, which
is determined based on the actual test results.
Benchmarks on arm64 and amd64:
name old time/op new time/op delta
pkg:strings goos:linux goarch:arm64
IndexAnyASCII/1:1-8 23.7ns ± 3% 28.5ns ± 0% +20.15% (p=0.008 n=5+5)
IndexAnyASCII/1:2-8 18.0ns ± 0% 33.1ns ± 0% +83.67% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 20.0ns ± 0% 36.0ns ± 0% +80.00% (p=0.029 n=4+4)
IndexAnyASCII/1:8-8 36.1ns ± 0% 36.0ns ± 0% ~ (p=0.095 n=5+4)
IndexAnyASCII/1:16-8 48.1ns ± 0% 36.0ns ± 0% -25.19% (p=0.029 n=4+4)
IndexAnyASCII/1:32-8 72.1ns ± 0% 36.0ns ± 0% -50.01% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 120ns ± 0% 39ns ± 0% -67.83% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.0ns ± 0% 28.5ns ± 0% -60.95% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 76.8ns ± 0% 77.0ns ± 0% ~ (p=1.000 n=5+5)
IndexAnyASCII/16:4-8 83.2ns ± 1% 83.0ns ± 0% ~ (p=0.770 n=5+5)
IndexAnyASCII/16:8-8 111ns ± 1% 107ns ± 0% -3.25% (p=0.008 n=5+5)
IndexAnyASCII/16:16-8 139ns ± 1% 137ns ± 0% -1.58% (p=0.008 n=5+5)
IndexAnyASCII/16:32-8 199ns ± 1% 197ns ± 0% -1.20% (p=0.008 n=5+5)
IndexAnyASCII/16:64-8 307ns ± 0% 313ns ± 0% +1.82% (p=0.016 n=5+4)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 0% -90.31% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 678ns ± 0% 683ns ± 0% +0.68% (p=0.008 n=5+5)
IndexAnyASCII/256:4-8 685ns ± 0% 683ns ± 0% -0.29% (p=0.000 n=5+4)
IndexAnyASCII/256:8-8 711ns ± 0% 708ns ± 0% -0.48% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 740ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:32-8 799ns ± 0% 798ns ± 0% -0.18% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 910ns ± 0% 914ns ± 0% +0.44% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.1ns ± 0% 19.0ns ± 0% -29.79% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.1ns ± 0% 33.0ns ± 0% -25.17% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 46.1ns ± 0% 33.1ns ± 0% -28.29% (p=0.016 n=4+5)
IndexAnyUTF8/1:8-8 85.1ns ± 0% 33.0ns ± 0% -61.18% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 36ns ± 0% -67.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:32-8 188ns ± 0% 36ns ± 0% -80.85% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 332ns ± 0% 39ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/16:1-8 293ns ± 0% 54ns ± 0% -81.56% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 349ns ± 0% -37.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 546ns ± 1% 349ns ± 0% -36.10% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.22µs ± 0% 0.35µs ± 0% -71.39% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.63µs ± 1% 0.42µs ± 0% -73.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.87µs ± 0% 0.42µs ± 0% -85.22% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.47µs ± 0% -90.98% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.26µs ± 0% 0.47µs ± 0% -88.85% (p=0.000 n=4+5)
IndexAnyUTF8/256:2-8 8.62µs ± 0% 5.15µs ± 0% -40.21% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-8 8.25µs ± 0% 5.15µs ± 0% -37.50% (p=0.016 n=5+4)
IndexAnyUTF8/256:8-8 19.2µs ± 1% 5.2µs ± 0% -73.08% (p=0.016 n=5+4)
IndexAnyUTF8/256:16-8 25.6µs ± 1% 6.3µs ± 0% -75.32% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.6µs ± 0% 6.3µs ± 0% -86.15% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-8 82.4µs ± 0% 7.0µs ± 0% -91.53% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 33.5ns ± 0% +45.65% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 33.5ns ± 0% +36.73% (p=0.016 n=4+5)
LastIndexAnyASCII/1:4-8 27.5ns ± 0% 35.5ns ± 0% +29.09% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-8 44.5ns ± 0% 35.5ns ± 0% -20.13% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-8 56.5ns ± 0% 35.5ns ± 0% -37.15% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 80.3ns ± 0% 35.5ns ± 0% -55.79% (p=0.000 n=5+4)
LastIndexAnyASCII/1:64-8 129ns ± 0% 40ns ± 0% -68.85% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.8ns ± 0% 72.7ns ± 0% -0.19% (p=0.016 n=4+5)
LastIndexAnyASCII/16:2-8 75.4ns ± 0% 75.1ns ± 0% ~ (p=0.127 n=5+5)
LastIndexAnyASCII/16:4-8 81.9ns ± 1% 80.2ns ± 0% -2.00% (p=0.008 n=5+5)
LastIndexAnyASCII/16:8-8 110ns ± 1% 108ns ± 0% -1.46% (p=0.008 n=5+5)
LastIndexAnyASCII/16:16-8 138ns ± 1% 134ns ± 0% -3.18% (p=0.008 n=5+5)
LastIndexAnyASCII/16:32-8 198ns ± 0% 197ns ± 0% -0.51% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 313ns ± 0% +1.30% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-8 652ns ± 0% 653ns ± 0% +0.21% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 656ns ± 0% 656ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:4-8 663ns ± 0% 663ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/256:8-8 691ns ± 0% 690ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/256:16-8 719ns ± 0% 715ns ± 0% -0.53% (p=0.000 n=5+4)
LastIndexAnyASCII/256:32-8 779ns ± 0% 780ns ± 0% +0.13% (p=0.029 n=4+4)
LastIndexAnyASCII/256:64-8 890ns ± 0% 894ns ± 0% +0.45% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-8 31.6ns ± 0% 33.5ns ± 0% +6.01% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 33.5ns ± 0% -30.99% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-8 48.6ns ± 0% 33.5ns ± 0% -31.13% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:8-8 89.6ns ± 0% 33.5ns ± 0% -62.56% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 113ns ± 1% 36ns ± 0% -68.47% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 190ns ± 0% 36ns ± 0% -81.26% (p=0.029 n=4+4)
LastIndexAnyUTF8/1:64-8 327ns ± 0% 40ns ± 0% -87.77% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-8 364ns ± 0% 158ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/16:2-8 636ns ± 0% 472ns ± 0% -25.79% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:4-8 630ns ± 0% 472ns ± 0% -25.03% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.28µs ± 0% 0.47µs ± 0% -63.09% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.53µs ± 0% -68.39% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-8 2.88µs ± 0% 0.53µs ± 0% -81.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-8 5.08µs ± 0% 0.57µs ± 0% -88.79% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.41µs ± 0% 2.03µs ± 0% -62.46% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:2-8 9.77µs ± 0% 7.14µs ± 0% -26.97% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.63µs ± 0% 7.14µs ± 0% -25.86% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.0µs ± 0% 7.1µs ± 0% -64.30% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.1µs ± 1% 8.0µs ± 0% -69.40% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 45.6µs ± 1% 8.0µs ± 0% -82.51% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 80.8µs ± 0% 8.6µs ± 0% -89.33% (p=0.016 n=5+4)
pkg:bytes goos:linux goarch:arm64
IndexAnyASCII/1:1-8 26.2ns ± 1% 26.5ns ± 0% +1.30% (p=0.016 n=5+4)
IndexAnyASCII/1:2-8 18.5ns ± 0% 26.5ns ± 0% +43.24% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 21.0ns ± 0% 26.5ns ± 0% +26.38% (p=0.008 n=5+5)
IndexAnyASCII/1:8-8 37.5ns ± 0% 26.5ns ± 0% -29.33% (p=0.000 n=5+4)
IndexAnyASCII/1:16-8 49.6ns ± 0% 26.5ns ± 0% -46.49% (p=0.008 n=5+5)
IndexAnyASCII/1:32-8 73.6ns ± 0% 30.1ns ± 0% -59.16% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 122ns ± 0% 33ns ± 0% -73.23% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.7ns ± 0% 33.4ns ± 0% -54.71% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 79.1ns ± 0% 78.9ns ± 0% -0.30% (p=0.016 n=4+5)
IndexAnyASCII/16:4-8 84.8ns ± 0% 86.1ns ± 0% +1.58% (p=0.016 n=5+4)
IndexAnyASCII/16:8-8 111ns ± 0% 111ns ± 0% ~ (all equal)
IndexAnyASCII/16:16-8 139ns ± 0% 144ns ± 0% +3.60% (p=0.016 n=4+5)
IndexAnyASCII/16:32-8 196ns ± 0% 207ns ± 0% +5.61% (p=0.016 n=5+4)
IndexAnyASCII/16:64-8 311ns ± 0% 320ns ± 0% +2.89% (p=0.016 n=4+5)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 1% -90.35% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 680ns ± 0% 680ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:4-8 686ns ± 0% 687ns ± 0% ~ (p=0.167 n=5+5)
IndexAnyASCII/256:8-8 713ns ± 0% 712ns ± 0% -0.14% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 744ns ± 0% +0.54% (p=0.016 n=5+4)
IndexAnyASCII/256:32-8 797ns ± 0% 808ns ± 0% +1.43% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 912ns ± 0% 921ns ± 0% +0.99% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.5ns ± 0% 26.5ns ± 0% -3.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.5ns ± 0% 26.5ns ± 0% -40.50% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 45.6ns ± 0% 26.5ns ± 0% -41.89% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-8 85.8ns ± 1% 26.5ns ± 0% -69.11% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 26ns ± 0% -76.00% (p=0.016 n=5+4)
IndexAnyUTF8/1:32-8 188ns ± 0% 30ns ± 0% -84.04% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 333ns ± 0% 33ns ± 0% -90.20% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-8 294ns ± 0% 235ns ± 0% -20.07% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 309ns ± 0% -45.12% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 558ns ± 1% 309ns ± 0% -44.60% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.23µs ± 0% 0.31µs ± 0% -74.79% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.62µs ± 2% 0.31µs ± 0% -80.93% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.86µs ± 0% 0.38µs ± 0% -86.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.42µs ± 0% -91.86% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.27µs ± 1% 3.30µs ± 1% -22.75% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-8 8.61µs ± 0% 4.45µs ± 0% -48.31% (p=0.016 n=4+5)
IndexAnyUTF8/256:4-8 8.44µs ± 0% 4.45µs ± 0% -47.23% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-8 19.2µs ± 0% 4.5µs ± 0% -76.78% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-8 25.6µs ± 0% 4.5µs ± 0% -82.63% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.4µs ± 0% 5.5µs ± 0% -87.85% (p=0.016 n=4+5)
IndexAnyUTF8/256:64-8 82.5µs ± 0% 6.2µs ± 0% -92.49% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 26.5ns ± 0% +15.02% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 26.5ns ± 0% +8.16% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-8 27.8ns ± 0% 26.5ns ± 0% -4.68% (p=0.029 n=4+4)
LastIndexAnyASCII/1:8-8 45.1ns ± 1% 26.5ns ± 0% -41.29% (p=0.000 n=5+4)
LastIndexAnyASCII/1:16-8 57.1ns ± 0% 26.5ns ± 0% -53.61% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 81.5ns ± 0% 30.0ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:64-8 129ns ± 0% 32ns ± 0% -74.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.6ns ± 0% 72.1ns ± 0% -0.63% (p=0.000 n=4+5)
LastIndexAnyASCII/16:2-8 77.2ns ± 0% 77.2ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:4-8 83.1ns ± 0% 83.2ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/16:8-8 109ns ± 1% 108ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:16-8 136ns ± 0% 136ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:32-8 195ns ± 0% 197ns ± 0% +0.82% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 309ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:1-8 653ns ± 0% 657ns ± 0% +0.61% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 659ns ± 0% 658ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/256:4-8 664ns ± 0% 663ns ± 0% ~ (p=0.095 n=5+4)
LastIndexAnyASCII/256:8-8 698ns ± 0% 689ns ± 0% -1.29% (p=0.008 n=5+5)
LastIndexAnyASCII/256:16-8 726ns ± 0% 717ns ± 0% -1.24% (p=0.008 n=5+5)
LastIndexAnyASCII/256:32-8 777ns ± 0% 779ns ± 0% ~ (p=0.079 n=5+4)
LastIndexAnyASCII/256:64-8 889ns ± 0% 890ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyUTF8/1:1-8 32.1ns ± 0% 26.5ns ± 0% -17.45% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 26.5ns ± 0% -45.52% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:4-8 49.6ns ± 0% 26.5ns ± 0% -46.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-8 91.9ns ± 0% 26.5ns ± 0% -71.18% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 114ns ± 1% 26ns ± 0% -76.84% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 203ns ± 6% 30ns ± 0% -85.25% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-8 330ns ± 0% 33ns ± 0% -90.14% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:1-8 365ns ± 0% 164ns ± 0% -55.04% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-8 638ns ± 0% 296ns ± 0% -53.58% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-8 634ns ± 0% 296ns ± 0% -53.31% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.30µs ± 0% 0.30µs ± 0% -77.18% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.30µs ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-8 2.90µs ± 0% 0.38µs ± 0% -87.00% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:64-8 5.10µs ± 0% 0.42µs ± 0% -91.78% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.42µs ± 0% 2.12µs ± 0% -60.92% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-8 9.79µs ± 0% 4.26µs ± 0% -56.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.66µs ± 0% 4.26µs ± 0% -55.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.4µs ± 0% 4.3µs ± 0% -79.10% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.0µs ± 1% 4.3µs ± 0% -83.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 46.0µs ± 0% 5.5µs ± 0% -88.09% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 81.1µs ± 0% 6.2µs ± 0% -92.38% (p=0.008 n=5+5)
name old time/op new time/op delta
pkg:strings goos:linux goarch:amd64
IndexAnyASCII/1:1-48 10.0ns ± 0% 13.3ns ± 0% +33.00% (p=0.008 n=5+5)
IndexAnyASCII/1:2-48 11.0ns ± 0% 15.5ns ± 0% +40.55% (p=0.016 n=4+5)
IndexAnyASCII/1:4-48 12.9ns ± 0% 15.4ns ± 0% +19.69% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 18.6ns ± 0% 15.5ns ± 0% -16.45% (p=0.000 n=4+5)
IndexAnyASCII/1:16-48 30.1ns ± 0% 16.9ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/1:32-48 53.1ns ± 0% 18.6ns ± 0% -64.95% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 98.9ns ± 0% 17.4ns ± 0% -82.41% (p=0.000 n=5+4)
IndexAnyASCII/16:1-48 35.0ns ± 0% 14.2ns ± 0% -59.47% (p=0.000 n=5+4)
IndexAnyASCII/16:2-48 35.5ns ± 0% 35.6ns ± 0% ~ (p=0.238 n=5+4)
IndexAnyASCII/16:4-48 40.8ns ± 0% 40.7ns ± 1% ~ (p=0.643 n=5+5)
IndexAnyASCII/16:8-48 50.8ns ± 0% 50.9ns ± 1% ~ (p=1.000 n=4+5)
IndexAnyASCII/16:16-48 64.0ns ± 1% 64.5ns ± 1% ~ (p=0.071 n=5+5)
IndexAnyASCII/16:32-48 98.3ns ± 0% 100.8ns ± 1% +2.52% (p=0.008 n=5+5)
IndexAnyASCII/16:64-48 156ns ± 0% 157ns ± 0% ~ (p=0.238 n=4+5)
IndexAnyASCII/256:1-48 299ns ± 0% 24ns ± 3% -92.12% (p=0.008 n=5+5)
IndexAnyASCII/256:2-48 303ns ± 0% 304ns ± 0% ~ (p=0.762 n=5+5)
IndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.476 n=5+5)
IndexAnyASCII/256:8-48 321ns ± 0% 321ns ± 0% ~ (p=0.429 n=4+5)
IndexAnyASCII/256:16-48 334ns ± 0% 335ns ± 0% ~ (p=0.079 n=5+4)
IndexAnyASCII/256:32-48 367ns ± 0% 365ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/256:64-48 431ns ± 1% 421ns ± 0% -2.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.2ns ± 0% 10.8ns ± 0% -37.21% (p=0.029 n=4+4)
IndexAnyUTF8/1:2-48 26.7ns ± 0% 15.6ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:4-48 28.2ns ± 0% 15.6ns ± 0% -44.68% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-48 48.8ns ± 0% 15.6ns ± 0% -68.03% (p=0.029 n=4+4)
IndexAnyUTF8/1:16-48 58.3ns ± 0% 16.2ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:32-48 103ns ± 0% 18ns ± 0% -82.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 182ns ± 0% 17ns ± 0% -90.53% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 197ns ± 0% 25ns ± 0% -87.34% (p=0.000 n=5+4)
IndexAnyUTF8/16:2-48 348ns ± 0% 163ns ± 0% -53.11% (p=0.000 n=5+4)
IndexAnyUTF8/16:4-48 374ns ± 0% 163ns ± 0% -56.37% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-48 716ns ± 0% 163ns ± 0% -77.22% (p=0.000 n=5+4)
IndexAnyUTF8/16:16-48 859ns ± 0% 175ns ± 0% -79.63% (p=0.000 n=5+4)
IndexAnyUTF8/16:32-48 1.58µs ± 0% 0.20µs ± 0% -87.01% (p=0.029 n=4+4)
IndexAnyUTF8/16:64-48 2.84µs ± 0% 0.19µs ± 1% -93.34% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.61µs ± 0% 0.27µs ± 0% -89.81% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 4.95µs ± 0% 2.23µs ± 0% -54.91% (p=0.016 n=5+4)
IndexAnyUTF8/256:4-48 5.55µs ± 0% 2.23µs ± 0% -59.72% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.2µs ± 0% -79.39% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 13.1µs ± 0% 2.5µs ± 0% -81.21% (p=0.016 n=4+5)
IndexAnyUTF8/256:32-48 24.7µs ± 0% 2.8µs ± 0% -88.49% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-48 45.0µs ± 0% 2.6µs ± 1% -94.23% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-48 13.9ns ± 0% 15.2ns ± 0% +9.35% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-48 14.4ns ± 0% 15.2ns ± 0% +5.56% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-48 16.7ns ± 0% 15.2ns ± 0% -8.98% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-48 24.0ns ± 0% 15.2ns ± 0% -36.67% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-48 35.6ns ± 0% 15.0ns ± 0% -57.82% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-48 68.9ns ± 0% 16.7ns ± 0% -75.75% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 104ns ± 0% 17ns ± 1% -83.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-48 35.0ns ± 0% 35.0ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 35.6ns ± 0% 35.6ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:4-48 41.0ns ± 0% 40.8ns ± 0% -0.49% (p=0.032 n=5+5)
LastIndexAnyASCII/16:8-48 50.9ns ± 0% 50.7ns ± 1% ~ (p=0.397 n=5+5)
LastIndexAnyASCII/16:16-48 64.3ns ± 1% 64.4ns ± 1% ~ (p=1.000 n=4+5)
LastIndexAnyASCII/16:32-48 100ns ± 0% 100ns ± 0% +0.38% (p=0.016 n=4+5)
LastIndexAnyASCII/16:64-48 157ns ± 1% 163ns ± 0% +3.82% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-48 302ns ± 0% 300ns ± 0% -0.53% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 305ns ± 0% 303ns ± 0% -0.66% (p=0.000 n=5+4)
LastIndexAnyASCII/256:4-48 313ns ± 0% 307ns ± 0% -2.04% (p=0.000 n=4+5)
LastIndexAnyASCII/256:8-48 323ns ± 0% 315ns ± 0% -2.48% (p=0.029 n=4+4)
LastIndexAnyASCII/256:16-48 333ns ± 0% 332ns ± 0% -0.30% (p=0.048 n=5+5)
LastIndexAnyASCII/256:32-48 366ns ± 0% 367ns ± 0% ~ (p=0.238 n=4+5)
LastIndexAnyASCII/256:64-48 430ns ± 0% 430ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyUTF8/1:1-48 21.1ns ± 0% 13.9ns ± 0% -34.00% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 29.5ns ± 0% 13.9ns ± 0% -52.95% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 31.6ns ± 0% 13.9ns ± 0% -55.96% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-48 51.1ns ± 0% 13.9ns ± 0% -72.81% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 58.9ns ± 0% 14.6ns ± 0% -75.23% (p=0.016 n=5+4)
LastIndexAnyUTF8/1:32-48 103ns ± 0% 16ns ± 1% -84.12% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 177ns ± 0% 17ns ± 1% -90.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 275ns ± 1% 105ns ± 0% -61.85% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:2-48 406ns ± 0% 216ns ± 0% -46.70% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 458ns ± 0% 216ns ± 0% -52.75% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:8-48 753ns ± 0% 216ns ± 0% -71.31% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:16-48 902ns ± 0% 221ns ± 0% -75.50% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-48 1.57µs ± 0% 0.24µs ± 0% -84.46% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-48 2.77µs ± 0% 0.24µs ± 0% -91.22% (p=0.000 n=5+4)
LastIndexAnyUTF8/256:1-48 4.06µs ± 0% 1.53µs ± 0% -62.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.92µs ± 0% 3.04µs ± 0% -48.55% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:4-48 6.82µs ± 0% 3.04µs ± 0% -55.34% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.5µs ± 0% 3.0µs ± 0% -73.48% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 14.1µs ± 0% 3.1µs ± 0% -77.85% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-48 24.5µs ± 0% 3.5µs ± 0% -85.85% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:64-48 44.0µs ± 0% 3.5µs ± 0% -92.12% (p=0.008 n=5+5)
pkg:bytes goos:linux goarch:amd64
IndexAnyASCII/1:1-48 9.56ns ± 0% 11.00ns ± 0% +15.06% (p=0.016 n=5+4)
IndexAnyASCII/1:2-48 11.0ns ± 0% 10.8ns ± 2% -1.64% (p=0.048 n=5+5)
IndexAnyASCII/1:4-48 13.9ns ± 0% 11.0ns ± 1% -21.15% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 19.6ns ± 0% 10.8ns ± 3% -44.90% (p=0.008 n=5+5)
IndexAnyASCII/1:16-48 31.1ns ± 0% 11.5ns ± 0% -63.02% (p=0.008 n=5+5)
IndexAnyASCII/1:32-48 54.0ns ± 0% 11.8ns ± 0% -78.15% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 100ns ± 0% 13ns ± 0% -86.89% (p=0.008 n=5+5)
IndexAnyASCII/16:1-48 35.5ns ± 0% 14.8ns ± 0% -58.26% (p=0.008 n=5+5)
IndexAnyASCII/16:2-48 36.2ns ± 1% 36.0ns ± 1% ~ (p=0.087 n=5+5)
IndexAnyASCII/16:4-48 40.3ns ± 1% 39.7ns ± 4% ~ (p=0.175 n=4+5)
IndexAnyASCII/16:8-48 48.7ns ± 5% 45.8ns ± 0% -6.02% (p=0.016 n=5+4)
IndexAnyASCII/16:16-48 64.1ns ±11% 62.1ns ± 1% ~ (p=0.143 n=5+5)
IndexAnyASCII/16:32-48 97.9ns ± 1% 98.3ns ± 1% ~ (p=0.294 n=5+5)
IndexAnyASCII/16:64-48 163ns ± 0% 157ns ± 0% -3.68% (p=0.008 n=5+5)
IndexAnyASCII/256:1-48 389ns ± 0% 25ns ± 0% -93.65% (p=0.000 n=5+4)
IndexAnyASCII/256:2-48 391ns ± 0% 307ns ± 0% -21.48% (p=0.000 n=5+4)
IndexAnyASCII/256:4-48 394ns ± 0% 323ns ± 0% -17.92% (p=0.008 n=5+5)
IndexAnyASCII/256:8-48 402ns ± 0% 323ns ± 0% -19.51% (p=0.008 n=5+5)
IndexAnyASCII/256:16-48 414ns ± 0% 334ns ± 0% -19.32% (p=0.016 n=4+5)
IndexAnyASCII/256:32-48 446ns ± 0% 367ns ± 0% -17.75% (p=0.016 n=5+4)
IndexAnyASCII/256:64-48 511ns ± 0% 424ns ± 0% -17.02% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.4ns ± 0% 11.0ns ± 0% -36.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-48 27.3ns ± 1% 11.0ns ± 0% -59.74% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-48 28.7ns ± 0% 11.0ns ± 0% -61.73% (p=0.008 n=5+5)
IndexAnyUTF8/1:8-48 49.2ns ± 0% 11.0ns ± 0% -77.66% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-48 56.0ns ± 0% 11.5ns ± 0% -79.46% (p=0.000 n=5+4)
IndexAnyUTF8/1:32-48 102ns ± 0% 12ns ± 0% -88.24% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 177ns ± 0% 13ns ± 0% -92.51% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 212ns ± 0% 112ns ± 0% -47.17% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-48 356ns ± 0% 159ns ± 1% -55.28% (p=0.000 n=4+5)
IndexAnyUTF8/16:4-48 372ns ± 0% 158ns ± 0% -57.47% (p=0.008 n=5+5)
IndexAnyUTF8/16:8-48 712ns ± 0% 159ns ± 1% -77.70% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-48 829ns ± 0% 129ns ± 0% -84.44% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-48 1.55µs ± 0% 0.16µs ± 0% -89.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-48 2.77µs ± 0% 0.14µs ± 0% -94.94% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.85µs ± 0% 1.63µs ± 1% -42.74% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 5.14µs ± 1% 2.03µs ± 0% -60.51% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-48 5.56µs ± 0% 2.03µs ± 0% -63.52% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.0µs ± 0% -81.22% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 12.9µs ± 0% 1.9µs ± 0% -85.55% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-48 24.2µs ± 0% 2.1µs ± 0% -91.29% (p=0.016 n=5+4)
IndexAnyUTF8/256:64-48 43.7µs ± 0% 2.0µs ± 0% -95.32% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-48 13.7ns ± 1% 12.8ns ± 0% -6.57% (p=0.016 n=5+4)
LastIndexAnyASCII/1:2-48 14.7ns ± 0% 12.7ns ± 1% -13.33% (p=0.000 n=4+5)
LastIndexAnyASCII/1:4-48 16.9ns ± 0% 12.7ns ± 1% -24.73% (p=0.000 n=4+5)
LastIndexAnyASCII/1:8-48 20.5ns ± 0% 12.7ns ± 0% -37.85% (p=0.000 n=4+5)
LastIndexAnyASCII/1:16-48 28.0ns ± 0% 11.7ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:32-48 69.8ns ± 0% 12.4ns ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 73.8ns ± 0% 13.3ns ± 0% -82.03% (p=0.000 n=4+5)
LastIndexAnyASCII/16:1-48 35.5ns ± 0% 35.5ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 36.0ns ± 0% 36.1ns ± 0% +0.28% (p=0.016 n=4+5)
LastIndexAnyASCII/16:4-48 40.3ns ± 2% 40.0ns ± 6% ~ (p=0.651 n=5+5)
LastIndexAnyASCII/16:8-48 50.3ns ± 0% 50.2ns ± 9% ~ (p=0.175 n=4+5)
LastIndexAnyASCII/16:16-48 62.4ns ± 4% 64.4ns ± 0% +3.28% (p=0.016 n=5+4)
LastIndexAnyASCII/16:32-48 98.9ns ± 0% 98.4ns ± 0% -0.53% (p=0.016 n=5+4)
LastIndexAnyASCII/16:64-48 160ns ± 1% 161ns ± 1% ~ (p=0.325 n=5+5)
LastIndexAnyASCII/256:1-48 300ns ± 0% 301ns ± 0% +0.33% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 304ns ± 0% 304ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.556 n=4+5)
LastIndexAnyASCII/256:8-48 320ns ± 0% 321ns ± 0% ~ (p=0.143 n=5+5)
LastIndexAnyASCII/256:16-48 333ns ± 0% 335ns ± 0% +0.60% (p=0.029 n=4+4)
LastIndexAnyASCII/256:32-48 367ns ± 0% 366ns ± 0% ~ (p=0.095 n=4+5)
LastIndexAnyASCII/256:64-48 431ns ± 0% 424ns ± 0% -1.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-48 19.7ns ± 1% 11.9ns ± 0% -39.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 27.6ns ± 1% 11.9ns ± 0% -56.82% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 29.9ns ± 0% 11.9ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/1:8-48 48.7ns ± 0% 11.9ns ± 0% -75.54% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 57.8ns ± 0% 11.4ns ± 0% -80.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:32-48 94.7ns ± 0% 12.2ns ± 0% -87.07% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 163ns ± 0% 13ns ± 1% -91.93% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 258ns ± 0% 88ns ± 0% -65.76% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-48 400ns ± 0% 162ns ± 0% -59.38% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 415ns ± 0% 162ns ± 0% -60.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-48 737ns ± 0% 162ns ± 0% -78.02% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:16-48 882ns ± 0% 128ns ± 0% -85.49% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-48 1.47µs ± 0% 0.16µs ± 0% -89.29% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:64-48 2.56µs ± 0% 0.14µs ± 0% -94.41% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:1-48 3.60µs ± 0% 1.23µs ± 0% -65.67% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.78µs ± 0% 2.18µs ± 0% -62.32% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-48 6.26µs ± 0% 2.18µs ± 0% -65.15% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.2µs ± 0% 2.2µs ± 0% -80.53% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 13.5µs ± 0% 1.9µs ± 0% -86.02% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:32-48 23.0µs ± 0% 2.1µs ± 0% -90.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-48 40.5µs ± 0% 2.1µs ± 0% -94.73% (p=0.008 n=5+5)
Change-Id: Ie05e306f8b184b989701868cb161ce8b3f18203b
Reviewed-on: https://go-review.googlesource.com/c/go/+/156998
Run-TryBot: eric fang <eric.fang@arm.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-12-23 02:15:44 +00:00
|
|
|
|
{"\x80", "\xffb", 0},
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"aaa", "a", 0},
|
|
|
|
|
|
{"abc", "xyz", -1},
|
|
|
|
|
|
{"abc", "xcz", 2},
|
|
|
|
|
|
{"ab☺c", "x☺yz", 2},
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
{"a☺b☻c☹d", "cx", len("a☺b☻")},
|
|
|
|
|
|
{"a☺b☻c☹d", "uvw☻xyz", len("a☺b")},
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"aRegExp*", ".(|)*+?^$[]", 7},
|
|
|
|
|
|
{dots + dots + dots, " ", -1},
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
{"012abcba210", "\xffb", 4},
|
|
|
|
|
|
{"012\x80bcb\x80210", "\xffb", 3},
|
strings, bytes: improve IndexAny and LastIndexAny performance
For the case of a pattern containing multi-byte rune, the time complexity of the
previous algorithm is O(nm), and if both input arguments are long, the search
performance will be poor. This CL improves the searching performance for these
cases by using IndexRune, which is mainly implemented with IndexByte and Index.
As IndexByte and Index are specially optimized with some powerful instructions
for short patterns (an UTF8 rune is 1 to 4 bytes), so they can help to reduce the
runtime complexity of IndexAny and LastIndexAny.
Another optimization method is using hash table, however, the actual test results
show that using indexrune is better, and the space complexity is lower.
There are two fast paths in IndexAny and LastIndexAny for cases where the length
of the input arguements are 1, and their locations are not exactly the same, which
is determined based on the actual test results.
Benchmarks on arm64 and amd64:
name old time/op new time/op delta
pkg:strings goos:linux goarch:arm64
IndexAnyASCII/1:1-8 23.7ns ± 3% 28.5ns ± 0% +20.15% (p=0.008 n=5+5)
IndexAnyASCII/1:2-8 18.0ns ± 0% 33.1ns ± 0% +83.67% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 20.0ns ± 0% 36.0ns ± 0% +80.00% (p=0.029 n=4+4)
IndexAnyASCII/1:8-8 36.1ns ± 0% 36.0ns ± 0% ~ (p=0.095 n=5+4)
IndexAnyASCII/1:16-8 48.1ns ± 0% 36.0ns ± 0% -25.19% (p=0.029 n=4+4)
IndexAnyASCII/1:32-8 72.1ns ± 0% 36.0ns ± 0% -50.01% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 120ns ± 0% 39ns ± 0% -67.83% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.0ns ± 0% 28.5ns ± 0% -60.95% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 76.8ns ± 0% 77.0ns ± 0% ~ (p=1.000 n=5+5)
IndexAnyASCII/16:4-8 83.2ns ± 1% 83.0ns ± 0% ~ (p=0.770 n=5+5)
IndexAnyASCII/16:8-8 111ns ± 1% 107ns ± 0% -3.25% (p=0.008 n=5+5)
IndexAnyASCII/16:16-8 139ns ± 1% 137ns ± 0% -1.58% (p=0.008 n=5+5)
IndexAnyASCII/16:32-8 199ns ± 1% 197ns ± 0% -1.20% (p=0.008 n=5+5)
IndexAnyASCII/16:64-8 307ns ± 0% 313ns ± 0% +1.82% (p=0.016 n=5+4)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 0% -90.31% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 678ns ± 0% 683ns ± 0% +0.68% (p=0.008 n=5+5)
IndexAnyASCII/256:4-8 685ns ± 0% 683ns ± 0% -0.29% (p=0.000 n=5+4)
IndexAnyASCII/256:8-8 711ns ± 0% 708ns ± 0% -0.48% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 740ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:32-8 799ns ± 0% 798ns ± 0% -0.18% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 910ns ± 0% 914ns ± 0% +0.44% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.1ns ± 0% 19.0ns ± 0% -29.79% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.1ns ± 0% 33.0ns ± 0% -25.17% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 46.1ns ± 0% 33.1ns ± 0% -28.29% (p=0.016 n=4+5)
IndexAnyUTF8/1:8-8 85.1ns ± 0% 33.0ns ± 0% -61.18% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 36ns ± 0% -67.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:32-8 188ns ± 0% 36ns ± 0% -80.85% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 332ns ± 0% 39ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/16:1-8 293ns ± 0% 54ns ± 0% -81.56% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 349ns ± 0% -37.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 546ns ± 1% 349ns ± 0% -36.10% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.22µs ± 0% 0.35µs ± 0% -71.39% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.63µs ± 1% 0.42µs ± 0% -73.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.87µs ± 0% 0.42µs ± 0% -85.22% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.47µs ± 0% -90.98% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.26µs ± 0% 0.47µs ± 0% -88.85% (p=0.000 n=4+5)
IndexAnyUTF8/256:2-8 8.62µs ± 0% 5.15µs ± 0% -40.21% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-8 8.25µs ± 0% 5.15µs ± 0% -37.50% (p=0.016 n=5+4)
IndexAnyUTF8/256:8-8 19.2µs ± 1% 5.2µs ± 0% -73.08% (p=0.016 n=5+4)
IndexAnyUTF8/256:16-8 25.6µs ± 1% 6.3µs ± 0% -75.32% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.6µs ± 0% 6.3µs ± 0% -86.15% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-8 82.4µs ± 0% 7.0µs ± 0% -91.53% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 33.5ns ± 0% +45.65% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 33.5ns ± 0% +36.73% (p=0.016 n=4+5)
LastIndexAnyASCII/1:4-8 27.5ns ± 0% 35.5ns ± 0% +29.09% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-8 44.5ns ± 0% 35.5ns ± 0% -20.13% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-8 56.5ns ± 0% 35.5ns ± 0% -37.15% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 80.3ns ± 0% 35.5ns ± 0% -55.79% (p=0.000 n=5+4)
LastIndexAnyASCII/1:64-8 129ns ± 0% 40ns ± 0% -68.85% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.8ns ± 0% 72.7ns ± 0% -0.19% (p=0.016 n=4+5)
LastIndexAnyASCII/16:2-8 75.4ns ± 0% 75.1ns ± 0% ~ (p=0.127 n=5+5)
LastIndexAnyASCII/16:4-8 81.9ns ± 1% 80.2ns ± 0% -2.00% (p=0.008 n=5+5)
LastIndexAnyASCII/16:8-8 110ns ± 1% 108ns ± 0% -1.46% (p=0.008 n=5+5)
LastIndexAnyASCII/16:16-8 138ns ± 1% 134ns ± 0% -3.18% (p=0.008 n=5+5)
LastIndexAnyASCII/16:32-8 198ns ± 0% 197ns ± 0% -0.51% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 313ns ± 0% +1.30% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-8 652ns ± 0% 653ns ± 0% +0.21% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 656ns ± 0% 656ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:4-8 663ns ± 0% 663ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/256:8-8 691ns ± 0% 690ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/256:16-8 719ns ± 0% 715ns ± 0% -0.53% (p=0.000 n=5+4)
LastIndexAnyASCII/256:32-8 779ns ± 0% 780ns ± 0% +0.13% (p=0.029 n=4+4)
LastIndexAnyASCII/256:64-8 890ns ± 0% 894ns ± 0% +0.45% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-8 31.6ns ± 0% 33.5ns ± 0% +6.01% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 33.5ns ± 0% -30.99% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-8 48.6ns ± 0% 33.5ns ± 0% -31.13% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:8-8 89.6ns ± 0% 33.5ns ± 0% -62.56% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 113ns ± 1% 36ns ± 0% -68.47% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 190ns ± 0% 36ns ± 0% -81.26% (p=0.029 n=4+4)
LastIndexAnyUTF8/1:64-8 327ns ± 0% 40ns ± 0% -87.77% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-8 364ns ± 0% 158ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/16:2-8 636ns ± 0% 472ns ± 0% -25.79% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:4-8 630ns ± 0% 472ns ± 0% -25.03% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.28µs ± 0% 0.47µs ± 0% -63.09% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.53µs ± 0% -68.39% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-8 2.88µs ± 0% 0.53µs ± 0% -81.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-8 5.08µs ± 0% 0.57µs ± 0% -88.79% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.41µs ± 0% 2.03µs ± 0% -62.46% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:2-8 9.77µs ± 0% 7.14µs ± 0% -26.97% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.63µs ± 0% 7.14µs ± 0% -25.86% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.0µs ± 0% 7.1µs ± 0% -64.30% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.1µs ± 1% 8.0µs ± 0% -69.40% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 45.6µs ± 1% 8.0µs ± 0% -82.51% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 80.8µs ± 0% 8.6µs ± 0% -89.33% (p=0.016 n=5+4)
pkg:bytes goos:linux goarch:arm64
IndexAnyASCII/1:1-8 26.2ns ± 1% 26.5ns ± 0% +1.30% (p=0.016 n=5+4)
IndexAnyASCII/1:2-8 18.5ns ± 0% 26.5ns ± 0% +43.24% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 21.0ns ± 0% 26.5ns ± 0% +26.38% (p=0.008 n=5+5)
IndexAnyASCII/1:8-8 37.5ns ± 0% 26.5ns ± 0% -29.33% (p=0.000 n=5+4)
IndexAnyASCII/1:16-8 49.6ns ± 0% 26.5ns ± 0% -46.49% (p=0.008 n=5+5)
IndexAnyASCII/1:32-8 73.6ns ± 0% 30.1ns ± 0% -59.16% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 122ns ± 0% 33ns ± 0% -73.23% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.7ns ± 0% 33.4ns ± 0% -54.71% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 79.1ns ± 0% 78.9ns ± 0% -0.30% (p=0.016 n=4+5)
IndexAnyASCII/16:4-8 84.8ns ± 0% 86.1ns ± 0% +1.58% (p=0.016 n=5+4)
IndexAnyASCII/16:8-8 111ns ± 0% 111ns ± 0% ~ (all equal)
IndexAnyASCII/16:16-8 139ns ± 0% 144ns ± 0% +3.60% (p=0.016 n=4+5)
IndexAnyASCII/16:32-8 196ns ± 0% 207ns ± 0% +5.61% (p=0.016 n=5+4)
IndexAnyASCII/16:64-8 311ns ± 0% 320ns ± 0% +2.89% (p=0.016 n=4+5)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 1% -90.35% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 680ns ± 0% 680ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:4-8 686ns ± 0% 687ns ± 0% ~ (p=0.167 n=5+5)
IndexAnyASCII/256:8-8 713ns ± 0% 712ns ± 0% -0.14% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 744ns ± 0% +0.54% (p=0.016 n=5+4)
IndexAnyASCII/256:32-8 797ns ± 0% 808ns ± 0% +1.43% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 912ns ± 0% 921ns ± 0% +0.99% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.5ns ± 0% 26.5ns ± 0% -3.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.5ns ± 0% 26.5ns ± 0% -40.50% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 45.6ns ± 0% 26.5ns ± 0% -41.89% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-8 85.8ns ± 1% 26.5ns ± 0% -69.11% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 26ns ± 0% -76.00% (p=0.016 n=5+4)
IndexAnyUTF8/1:32-8 188ns ± 0% 30ns ± 0% -84.04% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 333ns ± 0% 33ns ± 0% -90.20% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-8 294ns ± 0% 235ns ± 0% -20.07% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 309ns ± 0% -45.12% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 558ns ± 1% 309ns ± 0% -44.60% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.23µs ± 0% 0.31µs ± 0% -74.79% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.62µs ± 2% 0.31µs ± 0% -80.93% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.86µs ± 0% 0.38µs ± 0% -86.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.42µs ± 0% -91.86% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.27µs ± 1% 3.30µs ± 1% -22.75% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-8 8.61µs ± 0% 4.45µs ± 0% -48.31% (p=0.016 n=4+5)
IndexAnyUTF8/256:4-8 8.44µs ± 0% 4.45µs ± 0% -47.23% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-8 19.2µs ± 0% 4.5µs ± 0% -76.78% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-8 25.6µs ± 0% 4.5µs ± 0% -82.63% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.4µs ± 0% 5.5µs ± 0% -87.85% (p=0.016 n=4+5)
IndexAnyUTF8/256:64-8 82.5µs ± 0% 6.2µs ± 0% -92.49% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 26.5ns ± 0% +15.02% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 26.5ns ± 0% +8.16% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-8 27.8ns ± 0% 26.5ns ± 0% -4.68% (p=0.029 n=4+4)
LastIndexAnyASCII/1:8-8 45.1ns ± 1% 26.5ns ± 0% -41.29% (p=0.000 n=5+4)
LastIndexAnyASCII/1:16-8 57.1ns ± 0% 26.5ns ± 0% -53.61% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 81.5ns ± 0% 30.0ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:64-8 129ns ± 0% 32ns ± 0% -74.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.6ns ± 0% 72.1ns ± 0% -0.63% (p=0.000 n=4+5)
LastIndexAnyASCII/16:2-8 77.2ns ± 0% 77.2ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:4-8 83.1ns ± 0% 83.2ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/16:8-8 109ns ± 1% 108ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:16-8 136ns ± 0% 136ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:32-8 195ns ± 0% 197ns ± 0% +0.82% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 309ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:1-8 653ns ± 0% 657ns ± 0% +0.61% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 659ns ± 0% 658ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/256:4-8 664ns ± 0% 663ns ± 0% ~ (p=0.095 n=5+4)
LastIndexAnyASCII/256:8-8 698ns ± 0% 689ns ± 0% -1.29% (p=0.008 n=5+5)
LastIndexAnyASCII/256:16-8 726ns ± 0% 717ns ± 0% -1.24% (p=0.008 n=5+5)
LastIndexAnyASCII/256:32-8 777ns ± 0% 779ns ± 0% ~ (p=0.079 n=5+4)
LastIndexAnyASCII/256:64-8 889ns ± 0% 890ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyUTF8/1:1-8 32.1ns ± 0% 26.5ns ± 0% -17.45% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 26.5ns ± 0% -45.52% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:4-8 49.6ns ± 0% 26.5ns ± 0% -46.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-8 91.9ns ± 0% 26.5ns ± 0% -71.18% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 114ns ± 1% 26ns ± 0% -76.84% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 203ns ± 6% 30ns ± 0% -85.25% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-8 330ns ± 0% 33ns ± 0% -90.14% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:1-8 365ns ± 0% 164ns ± 0% -55.04% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-8 638ns ± 0% 296ns ± 0% -53.58% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-8 634ns ± 0% 296ns ± 0% -53.31% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.30µs ± 0% 0.30µs ± 0% -77.18% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.30µs ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-8 2.90µs ± 0% 0.38µs ± 0% -87.00% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:64-8 5.10µs ± 0% 0.42µs ± 0% -91.78% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.42µs ± 0% 2.12µs ± 0% -60.92% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-8 9.79µs ± 0% 4.26µs ± 0% -56.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.66µs ± 0% 4.26µs ± 0% -55.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.4µs ± 0% 4.3µs ± 0% -79.10% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.0µs ± 1% 4.3µs ± 0% -83.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 46.0µs ± 0% 5.5µs ± 0% -88.09% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 81.1µs ± 0% 6.2µs ± 0% -92.38% (p=0.008 n=5+5)
name old time/op new time/op delta
pkg:strings goos:linux goarch:amd64
IndexAnyASCII/1:1-48 10.0ns ± 0% 13.3ns ± 0% +33.00% (p=0.008 n=5+5)
IndexAnyASCII/1:2-48 11.0ns ± 0% 15.5ns ± 0% +40.55% (p=0.016 n=4+5)
IndexAnyASCII/1:4-48 12.9ns ± 0% 15.4ns ± 0% +19.69% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 18.6ns ± 0% 15.5ns ± 0% -16.45% (p=0.000 n=4+5)
IndexAnyASCII/1:16-48 30.1ns ± 0% 16.9ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/1:32-48 53.1ns ± 0% 18.6ns ± 0% -64.95% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 98.9ns ± 0% 17.4ns ± 0% -82.41% (p=0.000 n=5+4)
IndexAnyASCII/16:1-48 35.0ns ± 0% 14.2ns ± 0% -59.47% (p=0.000 n=5+4)
IndexAnyASCII/16:2-48 35.5ns ± 0% 35.6ns ± 0% ~ (p=0.238 n=5+4)
IndexAnyASCII/16:4-48 40.8ns ± 0% 40.7ns ± 1% ~ (p=0.643 n=5+5)
IndexAnyASCII/16:8-48 50.8ns ± 0% 50.9ns ± 1% ~ (p=1.000 n=4+5)
IndexAnyASCII/16:16-48 64.0ns ± 1% 64.5ns ± 1% ~ (p=0.071 n=5+5)
IndexAnyASCII/16:32-48 98.3ns ± 0% 100.8ns ± 1% +2.52% (p=0.008 n=5+5)
IndexAnyASCII/16:64-48 156ns ± 0% 157ns ± 0% ~ (p=0.238 n=4+5)
IndexAnyASCII/256:1-48 299ns ± 0% 24ns ± 3% -92.12% (p=0.008 n=5+5)
IndexAnyASCII/256:2-48 303ns ± 0% 304ns ± 0% ~ (p=0.762 n=5+5)
IndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.476 n=5+5)
IndexAnyASCII/256:8-48 321ns ± 0% 321ns ± 0% ~ (p=0.429 n=4+5)
IndexAnyASCII/256:16-48 334ns ± 0% 335ns ± 0% ~ (p=0.079 n=5+4)
IndexAnyASCII/256:32-48 367ns ± 0% 365ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/256:64-48 431ns ± 1% 421ns ± 0% -2.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.2ns ± 0% 10.8ns ± 0% -37.21% (p=0.029 n=4+4)
IndexAnyUTF8/1:2-48 26.7ns ± 0% 15.6ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:4-48 28.2ns ± 0% 15.6ns ± 0% -44.68% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-48 48.8ns ± 0% 15.6ns ± 0% -68.03% (p=0.029 n=4+4)
IndexAnyUTF8/1:16-48 58.3ns ± 0% 16.2ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:32-48 103ns ± 0% 18ns ± 0% -82.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 182ns ± 0% 17ns ± 0% -90.53% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 197ns ± 0% 25ns ± 0% -87.34% (p=0.000 n=5+4)
IndexAnyUTF8/16:2-48 348ns ± 0% 163ns ± 0% -53.11% (p=0.000 n=5+4)
IndexAnyUTF8/16:4-48 374ns ± 0% 163ns ± 0% -56.37% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-48 716ns ± 0% 163ns ± 0% -77.22% (p=0.000 n=5+4)
IndexAnyUTF8/16:16-48 859ns ± 0% 175ns ± 0% -79.63% (p=0.000 n=5+4)
IndexAnyUTF8/16:32-48 1.58µs ± 0% 0.20µs ± 0% -87.01% (p=0.029 n=4+4)
IndexAnyUTF8/16:64-48 2.84µs ± 0% 0.19µs ± 1% -93.34% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.61µs ± 0% 0.27µs ± 0% -89.81% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 4.95µs ± 0% 2.23µs ± 0% -54.91% (p=0.016 n=5+4)
IndexAnyUTF8/256:4-48 5.55µs ± 0% 2.23µs ± 0% -59.72% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.2µs ± 0% -79.39% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 13.1µs ± 0% 2.5µs ± 0% -81.21% (p=0.016 n=4+5)
IndexAnyUTF8/256:32-48 24.7µs ± 0% 2.8µs ± 0% -88.49% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-48 45.0µs ± 0% 2.6µs ± 1% -94.23% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-48 13.9ns ± 0% 15.2ns ± 0% +9.35% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-48 14.4ns ± 0% 15.2ns ± 0% +5.56% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-48 16.7ns ± 0% 15.2ns ± 0% -8.98% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-48 24.0ns ± 0% 15.2ns ± 0% -36.67% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-48 35.6ns ± 0% 15.0ns ± 0% -57.82% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-48 68.9ns ± 0% 16.7ns ± 0% -75.75% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 104ns ± 0% 17ns ± 1% -83.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-48 35.0ns ± 0% 35.0ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 35.6ns ± 0% 35.6ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:4-48 41.0ns ± 0% 40.8ns ± 0% -0.49% (p=0.032 n=5+5)
LastIndexAnyASCII/16:8-48 50.9ns ± 0% 50.7ns ± 1% ~ (p=0.397 n=5+5)
LastIndexAnyASCII/16:16-48 64.3ns ± 1% 64.4ns ± 1% ~ (p=1.000 n=4+5)
LastIndexAnyASCII/16:32-48 100ns ± 0% 100ns ± 0% +0.38% (p=0.016 n=4+5)
LastIndexAnyASCII/16:64-48 157ns ± 1% 163ns ± 0% +3.82% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-48 302ns ± 0% 300ns ± 0% -0.53% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 305ns ± 0% 303ns ± 0% -0.66% (p=0.000 n=5+4)
LastIndexAnyASCII/256:4-48 313ns ± 0% 307ns ± 0% -2.04% (p=0.000 n=4+5)
LastIndexAnyASCII/256:8-48 323ns ± 0% 315ns ± 0% -2.48% (p=0.029 n=4+4)
LastIndexAnyASCII/256:16-48 333ns ± 0% 332ns ± 0% -0.30% (p=0.048 n=5+5)
LastIndexAnyASCII/256:32-48 366ns ± 0% 367ns ± 0% ~ (p=0.238 n=4+5)
LastIndexAnyASCII/256:64-48 430ns ± 0% 430ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyUTF8/1:1-48 21.1ns ± 0% 13.9ns ± 0% -34.00% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 29.5ns ± 0% 13.9ns ± 0% -52.95% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 31.6ns ± 0% 13.9ns ± 0% -55.96% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-48 51.1ns ± 0% 13.9ns ± 0% -72.81% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 58.9ns ± 0% 14.6ns ± 0% -75.23% (p=0.016 n=5+4)
LastIndexAnyUTF8/1:32-48 103ns ± 0% 16ns ± 1% -84.12% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 177ns ± 0% 17ns ± 1% -90.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 275ns ± 1% 105ns ± 0% -61.85% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:2-48 406ns ± 0% 216ns ± 0% -46.70% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 458ns ± 0% 216ns ± 0% -52.75% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:8-48 753ns ± 0% 216ns ± 0% -71.31% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:16-48 902ns ± 0% 221ns ± 0% -75.50% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-48 1.57µs ± 0% 0.24µs ± 0% -84.46% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-48 2.77µs ± 0% 0.24µs ± 0% -91.22% (p=0.000 n=5+4)
LastIndexAnyUTF8/256:1-48 4.06µs ± 0% 1.53µs ± 0% -62.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.92µs ± 0% 3.04µs ± 0% -48.55% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:4-48 6.82µs ± 0% 3.04µs ± 0% -55.34% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.5µs ± 0% 3.0µs ± 0% -73.48% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 14.1µs ± 0% 3.1µs ± 0% -77.85% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-48 24.5µs ± 0% 3.5µs ± 0% -85.85% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:64-48 44.0µs ± 0% 3.5µs ± 0% -92.12% (p=0.008 n=5+5)
pkg:bytes goos:linux goarch:amd64
IndexAnyASCII/1:1-48 9.56ns ± 0% 11.00ns ± 0% +15.06% (p=0.016 n=5+4)
IndexAnyASCII/1:2-48 11.0ns ± 0% 10.8ns ± 2% -1.64% (p=0.048 n=5+5)
IndexAnyASCII/1:4-48 13.9ns ± 0% 11.0ns ± 1% -21.15% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 19.6ns ± 0% 10.8ns ± 3% -44.90% (p=0.008 n=5+5)
IndexAnyASCII/1:16-48 31.1ns ± 0% 11.5ns ± 0% -63.02% (p=0.008 n=5+5)
IndexAnyASCII/1:32-48 54.0ns ± 0% 11.8ns ± 0% -78.15% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 100ns ± 0% 13ns ± 0% -86.89% (p=0.008 n=5+5)
IndexAnyASCII/16:1-48 35.5ns ± 0% 14.8ns ± 0% -58.26% (p=0.008 n=5+5)
IndexAnyASCII/16:2-48 36.2ns ± 1% 36.0ns ± 1% ~ (p=0.087 n=5+5)
IndexAnyASCII/16:4-48 40.3ns ± 1% 39.7ns ± 4% ~ (p=0.175 n=4+5)
IndexAnyASCII/16:8-48 48.7ns ± 5% 45.8ns ± 0% -6.02% (p=0.016 n=5+4)
IndexAnyASCII/16:16-48 64.1ns ±11% 62.1ns ± 1% ~ (p=0.143 n=5+5)
IndexAnyASCII/16:32-48 97.9ns ± 1% 98.3ns ± 1% ~ (p=0.294 n=5+5)
IndexAnyASCII/16:64-48 163ns ± 0% 157ns ± 0% -3.68% (p=0.008 n=5+5)
IndexAnyASCII/256:1-48 389ns ± 0% 25ns ± 0% -93.65% (p=0.000 n=5+4)
IndexAnyASCII/256:2-48 391ns ± 0% 307ns ± 0% -21.48% (p=0.000 n=5+4)
IndexAnyASCII/256:4-48 394ns ± 0% 323ns ± 0% -17.92% (p=0.008 n=5+5)
IndexAnyASCII/256:8-48 402ns ± 0% 323ns ± 0% -19.51% (p=0.008 n=5+5)
IndexAnyASCII/256:16-48 414ns ± 0% 334ns ± 0% -19.32% (p=0.016 n=4+5)
IndexAnyASCII/256:32-48 446ns ± 0% 367ns ± 0% -17.75% (p=0.016 n=5+4)
IndexAnyASCII/256:64-48 511ns ± 0% 424ns ± 0% -17.02% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.4ns ± 0% 11.0ns ± 0% -36.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-48 27.3ns ± 1% 11.0ns ± 0% -59.74% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-48 28.7ns ± 0% 11.0ns ± 0% -61.73% (p=0.008 n=5+5)
IndexAnyUTF8/1:8-48 49.2ns ± 0% 11.0ns ± 0% -77.66% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-48 56.0ns ± 0% 11.5ns ± 0% -79.46% (p=0.000 n=5+4)
IndexAnyUTF8/1:32-48 102ns ± 0% 12ns ± 0% -88.24% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 177ns ± 0% 13ns ± 0% -92.51% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 212ns ± 0% 112ns ± 0% -47.17% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-48 356ns ± 0% 159ns ± 1% -55.28% (p=0.000 n=4+5)
IndexAnyUTF8/16:4-48 372ns ± 0% 158ns ± 0% -57.47% (p=0.008 n=5+5)
IndexAnyUTF8/16:8-48 712ns ± 0% 159ns ± 1% -77.70% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-48 829ns ± 0% 129ns ± 0% -84.44% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-48 1.55µs ± 0% 0.16µs ± 0% -89.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-48 2.77µs ± 0% 0.14µs ± 0% -94.94% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.85µs ± 0% 1.63µs ± 1% -42.74% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 5.14µs ± 1% 2.03µs ± 0% -60.51% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-48 5.56µs ± 0% 2.03µs ± 0% -63.52% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.0µs ± 0% -81.22% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 12.9µs ± 0% 1.9µs ± 0% -85.55% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-48 24.2µs ± 0% 2.1µs ± 0% -91.29% (p=0.016 n=5+4)
IndexAnyUTF8/256:64-48 43.7µs ± 0% 2.0µs ± 0% -95.32% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-48 13.7ns ± 1% 12.8ns ± 0% -6.57% (p=0.016 n=5+4)
LastIndexAnyASCII/1:2-48 14.7ns ± 0% 12.7ns ± 1% -13.33% (p=0.000 n=4+5)
LastIndexAnyASCII/1:4-48 16.9ns ± 0% 12.7ns ± 1% -24.73% (p=0.000 n=4+5)
LastIndexAnyASCII/1:8-48 20.5ns ± 0% 12.7ns ± 0% -37.85% (p=0.000 n=4+5)
LastIndexAnyASCII/1:16-48 28.0ns ± 0% 11.7ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:32-48 69.8ns ± 0% 12.4ns ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 73.8ns ± 0% 13.3ns ± 0% -82.03% (p=0.000 n=4+5)
LastIndexAnyASCII/16:1-48 35.5ns ± 0% 35.5ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 36.0ns ± 0% 36.1ns ± 0% +0.28% (p=0.016 n=4+5)
LastIndexAnyASCII/16:4-48 40.3ns ± 2% 40.0ns ± 6% ~ (p=0.651 n=5+5)
LastIndexAnyASCII/16:8-48 50.3ns ± 0% 50.2ns ± 9% ~ (p=0.175 n=4+5)
LastIndexAnyASCII/16:16-48 62.4ns ± 4% 64.4ns ± 0% +3.28% (p=0.016 n=5+4)
LastIndexAnyASCII/16:32-48 98.9ns ± 0% 98.4ns ± 0% -0.53% (p=0.016 n=5+4)
LastIndexAnyASCII/16:64-48 160ns ± 1% 161ns ± 1% ~ (p=0.325 n=5+5)
LastIndexAnyASCII/256:1-48 300ns ± 0% 301ns ± 0% +0.33% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 304ns ± 0% 304ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.556 n=4+5)
LastIndexAnyASCII/256:8-48 320ns ± 0% 321ns ± 0% ~ (p=0.143 n=5+5)
LastIndexAnyASCII/256:16-48 333ns ± 0% 335ns ± 0% +0.60% (p=0.029 n=4+4)
LastIndexAnyASCII/256:32-48 367ns ± 0% 366ns ± 0% ~ (p=0.095 n=4+5)
LastIndexAnyASCII/256:64-48 431ns ± 0% 424ns ± 0% -1.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-48 19.7ns ± 1% 11.9ns ± 0% -39.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 27.6ns ± 1% 11.9ns ± 0% -56.82% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 29.9ns ± 0% 11.9ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/1:8-48 48.7ns ± 0% 11.9ns ± 0% -75.54% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 57.8ns ± 0% 11.4ns ± 0% -80.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:32-48 94.7ns ± 0% 12.2ns ± 0% -87.07% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 163ns ± 0% 13ns ± 1% -91.93% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 258ns ± 0% 88ns ± 0% -65.76% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-48 400ns ± 0% 162ns ± 0% -59.38% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 415ns ± 0% 162ns ± 0% -60.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-48 737ns ± 0% 162ns ± 0% -78.02% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:16-48 882ns ± 0% 128ns ± 0% -85.49% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-48 1.47µs ± 0% 0.16µs ± 0% -89.29% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:64-48 2.56µs ± 0% 0.14µs ± 0% -94.41% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:1-48 3.60µs ± 0% 1.23µs ± 0% -65.67% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.78µs ± 0% 2.18µs ± 0% -62.32% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-48 6.26µs ± 0% 2.18µs ± 0% -65.15% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.2µs ± 0% 2.2µs ± 0% -80.53% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 13.5µs ± 0% 1.9µs ± 0% -86.02% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:32-48 23.0µs ± 0% 2.1µs ± 0% -90.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-48 40.5µs ± 0% 2.1µs ± 0% -94.73% (p=0.008 n=5+5)
Change-Id: Ie05e306f8b184b989701868cb161ce8b3f18203b
Reviewed-on: https://go-review.googlesource.com/c/go/+/156998
Run-TryBot: eric fang <eric.fang@arm.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-12-23 02:15:44 +00:00
|
|
|
|
{"0123456\xcf\x80abc", "\xcfb\x80", 10},
|
2010-03-26 13:05:04 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-11-12 12:47:50 -08:00
|
|
|
|
var lastIndexAnyTests = []BinOpTest{
|
|
|
|
|
|
{"", "", -1},
|
|
|
|
|
|
{"", "a", -1},
|
|
|
|
|
|
{"", "abc", -1},
|
|
|
|
|
|
{"a", "", -1},
|
|
|
|
|
|
{"a", "a", 0},
|
strings, bytes: improve IndexAny and LastIndexAny performance
For the case of a pattern containing multi-byte rune, the time complexity of the
previous algorithm is O(nm), and if both input arguments are long, the search
performance will be poor. This CL improves the searching performance for these
cases by using IndexRune, which is mainly implemented with IndexByte and Index.
As IndexByte and Index are specially optimized with some powerful instructions
for short patterns (an UTF8 rune is 1 to 4 bytes), so they can help to reduce the
runtime complexity of IndexAny and LastIndexAny.
Another optimization method is using hash table, however, the actual test results
show that using indexrune is better, and the space complexity is lower.
There are two fast paths in IndexAny and LastIndexAny for cases where the length
of the input arguements are 1, and their locations are not exactly the same, which
is determined based on the actual test results.
Benchmarks on arm64 and amd64:
name old time/op new time/op delta
pkg:strings goos:linux goarch:arm64
IndexAnyASCII/1:1-8 23.7ns ± 3% 28.5ns ± 0% +20.15% (p=0.008 n=5+5)
IndexAnyASCII/1:2-8 18.0ns ± 0% 33.1ns ± 0% +83.67% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 20.0ns ± 0% 36.0ns ± 0% +80.00% (p=0.029 n=4+4)
IndexAnyASCII/1:8-8 36.1ns ± 0% 36.0ns ± 0% ~ (p=0.095 n=5+4)
IndexAnyASCII/1:16-8 48.1ns ± 0% 36.0ns ± 0% -25.19% (p=0.029 n=4+4)
IndexAnyASCII/1:32-8 72.1ns ± 0% 36.0ns ± 0% -50.01% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 120ns ± 0% 39ns ± 0% -67.83% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.0ns ± 0% 28.5ns ± 0% -60.95% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 76.8ns ± 0% 77.0ns ± 0% ~ (p=1.000 n=5+5)
IndexAnyASCII/16:4-8 83.2ns ± 1% 83.0ns ± 0% ~ (p=0.770 n=5+5)
IndexAnyASCII/16:8-8 111ns ± 1% 107ns ± 0% -3.25% (p=0.008 n=5+5)
IndexAnyASCII/16:16-8 139ns ± 1% 137ns ± 0% -1.58% (p=0.008 n=5+5)
IndexAnyASCII/16:32-8 199ns ± 1% 197ns ± 0% -1.20% (p=0.008 n=5+5)
IndexAnyASCII/16:64-8 307ns ± 0% 313ns ± 0% +1.82% (p=0.016 n=5+4)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 0% -90.31% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 678ns ± 0% 683ns ± 0% +0.68% (p=0.008 n=5+5)
IndexAnyASCII/256:4-8 685ns ± 0% 683ns ± 0% -0.29% (p=0.000 n=5+4)
IndexAnyASCII/256:8-8 711ns ± 0% 708ns ± 0% -0.48% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 740ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:32-8 799ns ± 0% 798ns ± 0% -0.18% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 910ns ± 0% 914ns ± 0% +0.44% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.1ns ± 0% 19.0ns ± 0% -29.79% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.1ns ± 0% 33.0ns ± 0% -25.17% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 46.1ns ± 0% 33.1ns ± 0% -28.29% (p=0.016 n=4+5)
IndexAnyUTF8/1:8-8 85.1ns ± 0% 33.0ns ± 0% -61.18% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 36ns ± 0% -67.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:32-8 188ns ± 0% 36ns ± 0% -80.85% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 332ns ± 0% 39ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/16:1-8 293ns ± 0% 54ns ± 0% -81.56% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 349ns ± 0% -37.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 546ns ± 1% 349ns ± 0% -36.10% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.22µs ± 0% 0.35µs ± 0% -71.39% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.63µs ± 1% 0.42µs ± 0% -73.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.87µs ± 0% 0.42µs ± 0% -85.22% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.47µs ± 0% -90.98% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.26µs ± 0% 0.47µs ± 0% -88.85% (p=0.000 n=4+5)
IndexAnyUTF8/256:2-8 8.62µs ± 0% 5.15µs ± 0% -40.21% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-8 8.25µs ± 0% 5.15µs ± 0% -37.50% (p=0.016 n=5+4)
IndexAnyUTF8/256:8-8 19.2µs ± 1% 5.2µs ± 0% -73.08% (p=0.016 n=5+4)
IndexAnyUTF8/256:16-8 25.6µs ± 1% 6.3µs ± 0% -75.32% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.6µs ± 0% 6.3µs ± 0% -86.15% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-8 82.4µs ± 0% 7.0µs ± 0% -91.53% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 33.5ns ± 0% +45.65% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 33.5ns ± 0% +36.73% (p=0.016 n=4+5)
LastIndexAnyASCII/1:4-8 27.5ns ± 0% 35.5ns ± 0% +29.09% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-8 44.5ns ± 0% 35.5ns ± 0% -20.13% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-8 56.5ns ± 0% 35.5ns ± 0% -37.15% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 80.3ns ± 0% 35.5ns ± 0% -55.79% (p=0.000 n=5+4)
LastIndexAnyASCII/1:64-8 129ns ± 0% 40ns ± 0% -68.85% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.8ns ± 0% 72.7ns ± 0% -0.19% (p=0.016 n=4+5)
LastIndexAnyASCII/16:2-8 75.4ns ± 0% 75.1ns ± 0% ~ (p=0.127 n=5+5)
LastIndexAnyASCII/16:4-8 81.9ns ± 1% 80.2ns ± 0% -2.00% (p=0.008 n=5+5)
LastIndexAnyASCII/16:8-8 110ns ± 1% 108ns ± 0% -1.46% (p=0.008 n=5+5)
LastIndexAnyASCII/16:16-8 138ns ± 1% 134ns ± 0% -3.18% (p=0.008 n=5+5)
LastIndexAnyASCII/16:32-8 198ns ± 0% 197ns ± 0% -0.51% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 313ns ± 0% +1.30% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-8 652ns ± 0% 653ns ± 0% +0.21% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 656ns ± 0% 656ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:4-8 663ns ± 0% 663ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/256:8-8 691ns ± 0% 690ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/256:16-8 719ns ± 0% 715ns ± 0% -0.53% (p=0.000 n=5+4)
LastIndexAnyASCII/256:32-8 779ns ± 0% 780ns ± 0% +0.13% (p=0.029 n=4+4)
LastIndexAnyASCII/256:64-8 890ns ± 0% 894ns ± 0% +0.45% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-8 31.6ns ± 0% 33.5ns ± 0% +6.01% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 33.5ns ± 0% -30.99% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-8 48.6ns ± 0% 33.5ns ± 0% -31.13% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:8-8 89.6ns ± 0% 33.5ns ± 0% -62.56% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 113ns ± 1% 36ns ± 0% -68.47% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 190ns ± 0% 36ns ± 0% -81.26% (p=0.029 n=4+4)
LastIndexAnyUTF8/1:64-8 327ns ± 0% 40ns ± 0% -87.77% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-8 364ns ± 0% 158ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/16:2-8 636ns ± 0% 472ns ± 0% -25.79% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:4-8 630ns ± 0% 472ns ± 0% -25.03% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.28µs ± 0% 0.47µs ± 0% -63.09% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.53µs ± 0% -68.39% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-8 2.88µs ± 0% 0.53µs ± 0% -81.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-8 5.08µs ± 0% 0.57µs ± 0% -88.79% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.41µs ± 0% 2.03µs ± 0% -62.46% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:2-8 9.77µs ± 0% 7.14µs ± 0% -26.97% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.63µs ± 0% 7.14µs ± 0% -25.86% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.0µs ± 0% 7.1µs ± 0% -64.30% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.1µs ± 1% 8.0µs ± 0% -69.40% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 45.6µs ± 1% 8.0µs ± 0% -82.51% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 80.8µs ± 0% 8.6µs ± 0% -89.33% (p=0.016 n=5+4)
pkg:bytes goos:linux goarch:arm64
IndexAnyASCII/1:1-8 26.2ns ± 1% 26.5ns ± 0% +1.30% (p=0.016 n=5+4)
IndexAnyASCII/1:2-8 18.5ns ± 0% 26.5ns ± 0% +43.24% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 21.0ns ± 0% 26.5ns ± 0% +26.38% (p=0.008 n=5+5)
IndexAnyASCII/1:8-8 37.5ns ± 0% 26.5ns ± 0% -29.33% (p=0.000 n=5+4)
IndexAnyASCII/1:16-8 49.6ns ± 0% 26.5ns ± 0% -46.49% (p=0.008 n=5+5)
IndexAnyASCII/1:32-8 73.6ns ± 0% 30.1ns ± 0% -59.16% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 122ns ± 0% 33ns ± 0% -73.23% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.7ns ± 0% 33.4ns ± 0% -54.71% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 79.1ns ± 0% 78.9ns ± 0% -0.30% (p=0.016 n=4+5)
IndexAnyASCII/16:4-8 84.8ns ± 0% 86.1ns ± 0% +1.58% (p=0.016 n=5+4)
IndexAnyASCII/16:8-8 111ns ± 0% 111ns ± 0% ~ (all equal)
IndexAnyASCII/16:16-8 139ns ± 0% 144ns ± 0% +3.60% (p=0.016 n=4+5)
IndexAnyASCII/16:32-8 196ns ± 0% 207ns ± 0% +5.61% (p=0.016 n=5+4)
IndexAnyASCII/16:64-8 311ns ± 0% 320ns ± 0% +2.89% (p=0.016 n=4+5)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 1% -90.35% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 680ns ± 0% 680ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:4-8 686ns ± 0% 687ns ± 0% ~ (p=0.167 n=5+5)
IndexAnyASCII/256:8-8 713ns ± 0% 712ns ± 0% -0.14% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 744ns ± 0% +0.54% (p=0.016 n=5+4)
IndexAnyASCII/256:32-8 797ns ± 0% 808ns ± 0% +1.43% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 912ns ± 0% 921ns ± 0% +0.99% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.5ns ± 0% 26.5ns ± 0% -3.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.5ns ± 0% 26.5ns ± 0% -40.50% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 45.6ns ± 0% 26.5ns ± 0% -41.89% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-8 85.8ns ± 1% 26.5ns ± 0% -69.11% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 26ns ± 0% -76.00% (p=0.016 n=5+4)
IndexAnyUTF8/1:32-8 188ns ± 0% 30ns ± 0% -84.04% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 333ns ± 0% 33ns ± 0% -90.20% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-8 294ns ± 0% 235ns ± 0% -20.07% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 309ns ± 0% -45.12% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 558ns ± 1% 309ns ± 0% -44.60% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.23µs ± 0% 0.31µs ± 0% -74.79% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.62µs ± 2% 0.31µs ± 0% -80.93% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.86µs ± 0% 0.38µs ± 0% -86.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.42µs ± 0% -91.86% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.27µs ± 1% 3.30µs ± 1% -22.75% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-8 8.61µs ± 0% 4.45µs ± 0% -48.31% (p=0.016 n=4+5)
IndexAnyUTF8/256:4-8 8.44µs ± 0% 4.45µs ± 0% -47.23% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-8 19.2µs ± 0% 4.5µs ± 0% -76.78% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-8 25.6µs ± 0% 4.5µs ± 0% -82.63% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.4µs ± 0% 5.5µs ± 0% -87.85% (p=0.016 n=4+5)
IndexAnyUTF8/256:64-8 82.5µs ± 0% 6.2µs ± 0% -92.49% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 26.5ns ± 0% +15.02% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 26.5ns ± 0% +8.16% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-8 27.8ns ± 0% 26.5ns ± 0% -4.68% (p=0.029 n=4+4)
LastIndexAnyASCII/1:8-8 45.1ns ± 1% 26.5ns ± 0% -41.29% (p=0.000 n=5+4)
LastIndexAnyASCII/1:16-8 57.1ns ± 0% 26.5ns ± 0% -53.61% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 81.5ns ± 0% 30.0ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:64-8 129ns ± 0% 32ns ± 0% -74.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.6ns ± 0% 72.1ns ± 0% -0.63% (p=0.000 n=4+5)
LastIndexAnyASCII/16:2-8 77.2ns ± 0% 77.2ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:4-8 83.1ns ± 0% 83.2ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/16:8-8 109ns ± 1% 108ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:16-8 136ns ± 0% 136ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:32-8 195ns ± 0% 197ns ± 0% +0.82% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 309ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:1-8 653ns ± 0% 657ns ± 0% +0.61% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 659ns ± 0% 658ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/256:4-8 664ns ± 0% 663ns ± 0% ~ (p=0.095 n=5+4)
LastIndexAnyASCII/256:8-8 698ns ± 0% 689ns ± 0% -1.29% (p=0.008 n=5+5)
LastIndexAnyASCII/256:16-8 726ns ± 0% 717ns ± 0% -1.24% (p=0.008 n=5+5)
LastIndexAnyASCII/256:32-8 777ns ± 0% 779ns ± 0% ~ (p=0.079 n=5+4)
LastIndexAnyASCII/256:64-8 889ns ± 0% 890ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyUTF8/1:1-8 32.1ns ± 0% 26.5ns ± 0% -17.45% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 26.5ns ± 0% -45.52% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:4-8 49.6ns ± 0% 26.5ns ± 0% -46.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-8 91.9ns ± 0% 26.5ns ± 0% -71.18% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 114ns ± 1% 26ns ± 0% -76.84% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 203ns ± 6% 30ns ± 0% -85.25% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-8 330ns ± 0% 33ns ± 0% -90.14% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:1-8 365ns ± 0% 164ns ± 0% -55.04% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-8 638ns ± 0% 296ns ± 0% -53.58% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-8 634ns ± 0% 296ns ± 0% -53.31% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.30µs ± 0% 0.30µs ± 0% -77.18% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.30µs ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-8 2.90µs ± 0% 0.38µs ± 0% -87.00% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:64-8 5.10µs ± 0% 0.42µs ± 0% -91.78% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.42µs ± 0% 2.12µs ± 0% -60.92% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-8 9.79µs ± 0% 4.26µs ± 0% -56.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.66µs ± 0% 4.26µs ± 0% -55.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.4µs ± 0% 4.3µs ± 0% -79.10% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.0µs ± 1% 4.3µs ± 0% -83.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 46.0µs ± 0% 5.5µs ± 0% -88.09% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 81.1µs ± 0% 6.2µs ± 0% -92.38% (p=0.008 n=5+5)
name old time/op new time/op delta
pkg:strings goos:linux goarch:amd64
IndexAnyASCII/1:1-48 10.0ns ± 0% 13.3ns ± 0% +33.00% (p=0.008 n=5+5)
IndexAnyASCII/1:2-48 11.0ns ± 0% 15.5ns ± 0% +40.55% (p=0.016 n=4+5)
IndexAnyASCII/1:4-48 12.9ns ± 0% 15.4ns ± 0% +19.69% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 18.6ns ± 0% 15.5ns ± 0% -16.45% (p=0.000 n=4+5)
IndexAnyASCII/1:16-48 30.1ns ± 0% 16.9ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/1:32-48 53.1ns ± 0% 18.6ns ± 0% -64.95% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 98.9ns ± 0% 17.4ns ± 0% -82.41% (p=0.000 n=5+4)
IndexAnyASCII/16:1-48 35.0ns ± 0% 14.2ns ± 0% -59.47% (p=0.000 n=5+4)
IndexAnyASCII/16:2-48 35.5ns ± 0% 35.6ns ± 0% ~ (p=0.238 n=5+4)
IndexAnyASCII/16:4-48 40.8ns ± 0% 40.7ns ± 1% ~ (p=0.643 n=5+5)
IndexAnyASCII/16:8-48 50.8ns ± 0% 50.9ns ± 1% ~ (p=1.000 n=4+5)
IndexAnyASCII/16:16-48 64.0ns ± 1% 64.5ns ± 1% ~ (p=0.071 n=5+5)
IndexAnyASCII/16:32-48 98.3ns ± 0% 100.8ns ± 1% +2.52% (p=0.008 n=5+5)
IndexAnyASCII/16:64-48 156ns ± 0% 157ns ± 0% ~ (p=0.238 n=4+5)
IndexAnyASCII/256:1-48 299ns ± 0% 24ns ± 3% -92.12% (p=0.008 n=5+5)
IndexAnyASCII/256:2-48 303ns ± 0% 304ns ± 0% ~ (p=0.762 n=5+5)
IndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.476 n=5+5)
IndexAnyASCII/256:8-48 321ns ± 0% 321ns ± 0% ~ (p=0.429 n=4+5)
IndexAnyASCII/256:16-48 334ns ± 0% 335ns ± 0% ~ (p=0.079 n=5+4)
IndexAnyASCII/256:32-48 367ns ± 0% 365ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/256:64-48 431ns ± 1% 421ns ± 0% -2.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.2ns ± 0% 10.8ns ± 0% -37.21% (p=0.029 n=4+4)
IndexAnyUTF8/1:2-48 26.7ns ± 0% 15.6ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:4-48 28.2ns ± 0% 15.6ns ± 0% -44.68% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-48 48.8ns ± 0% 15.6ns ± 0% -68.03% (p=0.029 n=4+4)
IndexAnyUTF8/1:16-48 58.3ns ± 0% 16.2ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:32-48 103ns ± 0% 18ns ± 0% -82.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 182ns ± 0% 17ns ± 0% -90.53% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 197ns ± 0% 25ns ± 0% -87.34% (p=0.000 n=5+4)
IndexAnyUTF8/16:2-48 348ns ± 0% 163ns ± 0% -53.11% (p=0.000 n=5+4)
IndexAnyUTF8/16:4-48 374ns ± 0% 163ns ± 0% -56.37% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-48 716ns ± 0% 163ns ± 0% -77.22% (p=0.000 n=5+4)
IndexAnyUTF8/16:16-48 859ns ± 0% 175ns ± 0% -79.63% (p=0.000 n=5+4)
IndexAnyUTF8/16:32-48 1.58µs ± 0% 0.20µs ± 0% -87.01% (p=0.029 n=4+4)
IndexAnyUTF8/16:64-48 2.84µs ± 0% 0.19µs ± 1% -93.34% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.61µs ± 0% 0.27µs ± 0% -89.81% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 4.95µs ± 0% 2.23µs ± 0% -54.91% (p=0.016 n=5+4)
IndexAnyUTF8/256:4-48 5.55µs ± 0% 2.23µs ± 0% -59.72% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.2µs ± 0% -79.39% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 13.1µs ± 0% 2.5µs ± 0% -81.21% (p=0.016 n=4+5)
IndexAnyUTF8/256:32-48 24.7µs ± 0% 2.8µs ± 0% -88.49% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-48 45.0µs ± 0% 2.6µs ± 1% -94.23% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-48 13.9ns ± 0% 15.2ns ± 0% +9.35% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-48 14.4ns ± 0% 15.2ns ± 0% +5.56% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-48 16.7ns ± 0% 15.2ns ± 0% -8.98% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-48 24.0ns ± 0% 15.2ns ± 0% -36.67% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-48 35.6ns ± 0% 15.0ns ± 0% -57.82% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-48 68.9ns ± 0% 16.7ns ± 0% -75.75% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 104ns ± 0% 17ns ± 1% -83.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-48 35.0ns ± 0% 35.0ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 35.6ns ± 0% 35.6ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:4-48 41.0ns ± 0% 40.8ns ± 0% -0.49% (p=0.032 n=5+5)
LastIndexAnyASCII/16:8-48 50.9ns ± 0% 50.7ns ± 1% ~ (p=0.397 n=5+5)
LastIndexAnyASCII/16:16-48 64.3ns ± 1% 64.4ns ± 1% ~ (p=1.000 n=4+5)
LastIndexAnyASCII/16:32-48 100ns ± 0% 100ns ± 0% +0.38% (p=0.016 n=4+5)
LastIndexAnyASCII/16:64-48 157ns ± 1% 163ns ± 0% +3.82% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-48 302ns ± 0% 300ns ± 0% -0.53% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 305ns ± 0% 303ns ± 0% -0.66% (p=0.000 n=5+4)
LastIndexAnyASCII/256:4-48 313ns ± 0% 307ns ± 0% -2.04% (p=0.000 n=4+5)
LastIndexAnyASCII/256:8-48 323ns ± 0% 315ns ± 0% -2.48% (p=0.029 n=4+4)
LastIndexAnyASCII/256:16-48 333ns ± 0% 332ns ± 0% -0.30% (p=0.048 n=5+5)
LastIndexAnyASCII/256:32-48 366ns ± 0% 367ns ± 0% ~ (p=0.238 n=4+5)
LastIndexAnyASCII/256:64-48 430ns ± 0% 430ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyUTF8/1:1-48 21.1ns ± 0% 13.9ns ± 0% -34.00% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 29.5ns ± 0% 13.9ns ± 0% -52.95% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 31.6ns ± 0% 13.9ns ± 0% -55.96% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-48 51.1ns ± 0% 13.9ns ± 0% -72.81% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 58.9ns ± 0% 14.6ns ± 0% -75.23% (p=0.016 n=5+4)
LastIndexAnyUTF8/1:32-48 103ns ± 0% 16ns ± 1% -84.12% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 177ns ± 0% 17ns ± 1% -90.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 275ns ± 1% 105ns ± 0% -61.85% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:2-48 406ns ± 0% 216ns ± 0% -46.70% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 458ns ± 0% 216ns ± 0% -52.75% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:8-48 753ns ± 0% 216ns ± 0% -71.31% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:16-48 902ns ± 0% 221ns ± 0% -75.50% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-48 1.57µs ± 0% 0.24µs ± 0% -84.46% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-48 2.77µs ± 0% 0.24µs ± 0% -91.22% (p=0.000 n=5+4)
LastIndexAnyUTF8/256:1-48 4.06µs ± 0% 1.53µs ± 0% -62.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.92µs ± 0% 3.04µs ± 0% -48.55% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:4-48 6.82µs ± 0% 3.04µs ± 0% -55.34% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.5µs ± 0% 3.0µs ± 0% -73.48% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 14.1µs ± 0% 3.1µs ± 0% -77.85% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-48 24.5µs ± 0% 3.5µs ± 0% -85.85% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:64-48 44.0µs ± 0% 3.5µs ± 0% -92.12% (p=0.008 n=5+5)
pkg:bytes goos:linux goarch:amd64
IndexAnyASCII/1:1-48 9.56ns ± 0% 11.00ns ± 0% +15.06% (p=0.016 n=5+4)
IndexAnyASCII/1:2-48 11.0ns ± 0% 10.8ns ± 2% -1.64% (p=0.048 n=5+5)
IndexAnyASCII/1:4-48 13.9ns ± 0% 11.0ns ± 1% -21.15% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 19.6ns ± 0% 10.8ns ± 3% -44.90% (p=0.008 n=5+5)
IndexAnyASCII/1:16-48 31.1ns ± 0% 11.5ns ± 0% -63.02% (p=0.008 n=5+5)
IndexAnyASCII/1:32-48 54.0ns ± 0% 11.8ns ± 0% -78.15% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 100ns ± 0% 13ns ± 0% -86.89% (p=0.008 n=5+5)
IndexAnyASCII/16:1-48 35.5ns ± 0% 14.8ns ± 0% -58.26% (p=0.008 n=5+5)
IndexAnyASCII/16:2-48 36.2ns ± 1% 36.0ns ± 1% ~ (p=0.087 n=5+5)
IndexAnyASCII/16:4-48 40.3ns ± 1% 39.7ns ± 4% ~ (p=0.175 n=4+5)
IndexAnyASCII/16:8-48 48.7ns ± 5% 45.8ns ± 0% -6.02% (p=0.016 n=5+4)
IndexAnyASCII/16:16-48 64.1ns ±11% 62.1ns ± 1% ~ (p=0.143 n=5+5)
IndexAnyASCII/16:32-48 97.9ns ± 1% 98.3ns ± 1% ~ (p=0.294 n=5+5)
IndexAnyASCII/16:64-48 163ns ± 0% 157ns ± 0% -3.68% (p=0.008 n=5+5)
IndexAnyASCII/256:1-48 389ns ± 0% 25ns ± 0% -93.65% (p=0.000 n=5+4)
IndexAnyASCII/256:2-48 391ns ± 0% 307ns ± 0% -21.48% (p=0.000 n=5+4)
IndexAnyASCII/256:4-48 394ns ± 0% 323ns ± 0% -17.92% (p=0.008 n=5+5)
IndexAnyASCII/256:8-48 402ns ± 0% 323ns ± 0% -19.51% (p=0.008 n=5+5)
IndexAnyASCII/256:16-48 414ns ± 0% 334ns ± 0% -19.32% (p=0.016 n=4+5)
IndexAnyASCII/256:32-48 446ns ± 0% 367ns ± 0% -17.75% (p=0.016 n=5+4)
IndexAnyASCII/256:64-48 511ns ± 0% 424ns ± 0% -17.02% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.4ns ± 0% 11.0ns ± 0% -36.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-48 27.3ns ± 1% 11.0ns ± 0% -59.74% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-48 28.7ns ± 0% 11.0ns ± 0% -61.73% (p=0.008 n=5+5)
IndexAnyUTF8/1:8-48 49.2ns ± 0% 11.0ns ± 0% -77.66% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-48 56.0ns ± 0% 11.5ns ± 0% -79.46% (p=0.000 n=5+4)
IndexAnyUTF8/1:32-48 102ns ± 0% 12ns ± 0% -88.24% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 177ns ± 0% 13ns ± 0% -92.51% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 212ns ± 0% 112ns ± 0% -47.17% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-48 356ns ± 0% 159ns ± 1% -55.28% (p=0.000 n=4+5)
IndexAnyUTF8/16:4-48 372ns ± 0% 158ns ± 0% -57.47% (p=0.008 n=5+5)
IndexAnyUTF8/16:8-48 712ns ± 0% 159ns ± 1% -77.70% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-48 829ns ± 0% 129ns ± 0% -84.44% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-48 1.55µs ± 0% 0.16µs ± 0% -89.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-48 2.77µs ± 0% 0.14µs ± 0% -94.94% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.85µs ± 0% 1.63µs ± 1% -42.74% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 5.14µs ± 1% 2.03µs ± 0% -60.51% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-48 5.56µs ± 0% 2.03µs ± 0% -63.52% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.0µs ± 0% -81.22% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 12.9µs ± 0% 1.9µs ± 0% -85.55% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-48 24.2µs ± 0% 2.1µs ± 0% -91.29% (p=0.016 n=5+4)
IndexAnyUTF8/256:64-48 43.7µs ± 0% 2.0µs ± 0% -95.32% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-48 13.7ns ± 1% 12.8ns ± 0% -6.57% (p=0.016 n=5+4)
LastIndexAnyASCII/1:2-48 14.7ns ± 0% 12.7ns ± 1% -13.33% (p=0.000 n=4+5)
LastIndexAnyASCII/1:4-48 16.9ns ± 0% 12.7ns ± 1% -24.73% (p=0.000 n=4+5)
LastIndexAnyASCII/1:8-48 20.5ns ± 0% 12.7ns ± 0% -37.85% (p=0.000 n=4+5)
LastIndexAnyASCII/1:16-48 28.0ns ± 0% 11.7ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:32-48 69.8ns ± 0% 12.4ns ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 73.8ns ± 0% 13.3ns ± 0% -82.03% (p=0.000 n=4+5)
LastIndexAnyASCII/16:1-48 35.5ns ± 0% 35.5ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 36.0ns ± 0% 36.1ns ± 0% +0.28% (p=0.016 n=4+5)
LastIndexAnyASCII/16:4-48 40.3ns ± 2% 40.0ns ± 6% ~ (p=0.651 n=5+5)
LastIndexAnyASCII/16:8-48 50.3ns ± 0% 50.2ns ± 9% ~ (p=0.175 n=4+5)
LastIndexAnyASCII/16:16-48 62.4ns ± 4% 64.4ns ± 0% +3.28% (p=0.016 n=5+4)
LastIndexAnyASCII/16:32-48 98.9ns ± 0% 98.4ns ± 0% -0.53% (p=0.016 n=5+4)
LastIndexAnyASCII/16:64-48 160ns ± 1% 161ns ± 1% ~ (p=0.325 n=5+5)
LastIndexAnyASCII/256:1-48 300ns ± 0% 301ns ± 0% +0.33% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 304ns ± 0% 304ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.556 n=4+5)
LastIndexAnyASCII/256:8-48 320ns ± 0% 321ns ± 0% ~ (p=0.143 n=5+5)
LastIndexAnyASCII/256:16-48 333ns ± 0% 335ns ± 0% +0.60% (p=0.029 n=4+4)
LastIndexAnyASCII/256:32-48 367ns ± 0% 366ns ± 0% ~ (p=0.095 n=4+5)
LastIndexAnyASCII/256:64-48 431ns ± 0% 424ns ± 0% -1.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-48 19.7ns ± 1% 11.9ns ± 0% -39.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 27.6ns ± 1% 11.9ns ± 0% -56.82% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 29.9ns ± 0% 11.9ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/1:8-48 48.7ns ± 0% 11.9ns ± 0% -75.54% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 57.8ns ± 0% 11.4ns ± 0% -80.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:32-48 94.7ns ± 0% 12.2ns ± 0% -87.07% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 163ns ± 0% 13ns ± 1% -91.93% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 258ns ± 0% 88ns ± 0% -65.76% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-48 400ns ± 0% 162ns ± 0% -59.38% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 415ns ± 0% 162ns ± 0% -60.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-48 737ns ± 0% 162ns ± 0% -78.02% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:16-48 882ns ± 0% 128ns ± 0% -85.49% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-48 1.47µs ± 0% 0.16µs ± 0% -89.29% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:64-48 2.56µs ± 0% 0.14µs ± 0% -94.41% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:1-48 3.60µs ± 0% 1.23µs ± 0% -65.67% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.78µs ± 0% 2.18µs ± 0% -62.32% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-48 6.26µs ± 0% 2.18µs ± 0% -65.15% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.2µs ± 0% 2.2µs ± 0% -80.53% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 13.5µs ± 0% 1.9µs ± 0% -86.02% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:32-48 23.0µs ± 0% 2.1µs ± 0% -90.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-48 40.5µs ± 0% 2.1µs ± 0% -94.73% (p=0.008 n=5+5)
Change-Id: Ie05e306f8b184b989701868cb161ce8b3f18203b
Reviewed-on: https://go-review.googlesource.com/c/go/+/156998
Run-TryBot: eric fang <eric.fang@arm.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-12-23 02:15:44 +00:00
|
|
|
|
{"\x80", "\xffb", 0},
|
2010-11-12 12:47:50 -08:00
|
|
|
|
{"aaa", "a", 2},
|
|
|
|
|
|
{"abc", "xyz", -1},
|
|
|
|
|
|
{"abc", "ab", 1},
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
{"ab☺c", "x☺yz", 2},
|
|
|
|
|
|
{"a☺b☻c☹d", "cx", len("a☺b☻")},
|
|
|
|
|
|
{"a☺b☻c☹d", "uvw☻xyz", len("a☺b")},
|
2010-11-12 12:47:50 -08:00
|
|
|
|
{"a.RegExp*", ".(|)*+?^$[]", 8},
|
|
|
|
|
|
{dots + dots + dots, " ", -1},
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
{"012abcba210", "\xffb", 6},
|
|
|
|
|
|
{"012\x80bcb\x80210", "\xffb", 7},
|
strings, bytes: improve IndexAny and LastIndexAny performance
For the case of a pattern containing multi-byte rune, the time complexity of the
previous algorithm is O(nm), and if both input arguments are long, the search
performance will be poor. This CL improves the searching performance for these
cases by using IndexRune, which is mainly implemented with IndexByte and Index.
As IndexByte and Index are specially optimized with some powerful instructions
for short patterns (an UTF8 rune is 1 to 4 bytes), so they can help to reduce the
runtime complexity of IndexAny and LastIndexAny.
Another optimization method is using hash table, however, the actual test results
show that using indexrune is better, and the space complexity is lower.
There are two fast paths in IndexAny and LastIndexAny for cases where the length
of the input arguements are 1, and their locations are not exactly the same, which
is determined based on the actual test results.
Benchmarks on arm64 and amd64:
name old time/op new time/op delta
pkg:strings goos:linux goarch:arm64
IndexAnyASCII/1:1-8 23.7ns ± 3% 28.5ns ± 0% +20.15% (p=0.008 n=5+5)
IndexAnyASCII/1:2-8 18.0ns ± 0% 33.1ns ± 0% +83.67% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 20.0ns ± 0% 36.0ns ± 0% +80.00% (p=0.029 n=4+4)
IndexAnyASCII/1:8-8 36.1ns ± 0% 36.0ns ± 0% ~ (p=0.095 n=5+4)
IndexAnyASCII/1:16-8 48.1ns ± 0% 36.0ns ± 0% -25.19% (p=0.029 n=4+4)
IndexAnyASCII/1:32-8 72.1ns ± 0% 36.0ns ± 0% -50.01% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 120ns ± 0% 39ns ± 0% -67.83% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.0ns ± 0% 28.5ns ± 0% -60.95% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 76.8ns ± 0% 77.0ns ± 0% ~ (p=1.000 n=5+5)
IndexAnyASCII/16:4-8 83.2ns ± 1% 83.0ns ± 0% ~ (p=0.770 n=5+5)
IndexAnyASCII/16:8-8 111ns ± 1% 107ns ± 0% -3.25% (p=0.008 n=5+5)
IndexAnyASCII/16:16-8 139ns ± 1% 137ns ± 0% -1.58% (p=0.008 n=5+5)
IndexAnyASCII/16:32-8 199ns ± 1% 197ns ± 0% -1.20% (p=0.008 n=5+5)
IndexAnyASCII/16:64-8 307ns ± 0% 313ns ± 0% +1.82% (p=0.016 n=5+4)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 0% -90.31% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 678ns ± 0% 683ns ± 0% +0.68% (p=0.008 n=5+5)
IndexAnyASCII/256:4-8 685ns ± 0% 683ns ± 0% -0.29% (p=0.000 n=5+4)
IndexAnyASCII/256:8-8 711ns ± 0% 708ns ± 0% -0.48% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 740ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:32-8 799ns ± 0% 798ns ± 0% -0.18% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 910ns ± 0% 914ns ± 0% +0.44% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.1ns ± 0% 19.0ns ± 0% -29.79% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.1ns ± 0% 33.0ns ± 0% -25.17% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 46.1ns ± 0% 33.1ns ± 0% -28.29% (p=0.016 n=4+5)
IndexAnyUTF8/1:8-8 85.1ns ± 0% 33.0ns ± 0% -61.18% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 36ns ± 0% -67.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:32-8 188ns ± 0% 36ns ± 0% -80.85% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 332ns ± 0% 39ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/16:1-8 293ns ± 0% 54ns ± 0% -81.56% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 349ns ± 0% -37.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 546ns ± 1% 349ns ± 0% -36.10% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.22µs ± 0% 0.35µs ± 0% -71.39% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.63µs ± 1% 0.42µs ± 0% -73.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.87µs ± 0% 0.42µs ± 0% -85.22% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.47µs ± 0% -90.98% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.26µs ± 0% 0.47µs ± 0% -88.85% (p=0.000 n=4+5)
IndexAnyUTF8/256:2-8 8.62µs ± 0% 5.15µs ± 0% -40.21% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-8 8.25µs ± 0% 5.15µs ± 0% -37.50% (p=0.016 n=5+4)
IndexAnyUTF8/256:8-8 19.2µs ± 1% 5.2µs ± 0% -73.08% (p=0.016 n=5+4)
IndexAnyUTF8/256:16-8 25.6µs ± 1% 6.3µs ± 0% -75.32% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.6µs ± 0% 6.3µs ± 0% -86.15% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-8 82.4µs ± 0% 7.0µs ± 0% -91.53% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 33.5ns ± 0% +45.65% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 33.5ns ± 0% +36.73% (p=0.016 n=4+5)
LastIndexAnyASCII/1:4-8 27.5ns ± 0% 35.5ns ± 0% +29.09% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-8 44.5ns ± 0% 35.5ns ± 0% -20.13% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-8 56.5ns ± 0% 35.5ns ± 0% -37.15% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 80.3ns ± 0% 35.5ns ± 0% -55.79% (p=0.000 n=5+4)
LastIndexAnyASCII/1:64-8 129ns ± 0% 40ns ± 0% -68.85% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.8ns ± 0% 72.7ns ± 0% -0.19% (p=0.016 n=4+5)
LastIndexAnyASCII/16:2-8 75.4ns ± 0% 75.1ns ± 0% ~ (p=0.127 n=5+5)
LastIndexAnyASCII/16:4-8 81.9ns ± 1% 80.2ns ± 0% -2.00% (p=0.008 n=5+5)
LastIndexAnyASCII/16:8-8 110ns ± 1% 108ns ± 0% -1.46% (p=0.008 n=5+5)
LastIndexAnyASCII/16:16-8 138ns ± 1% 134ns ± 0% -3.18% (p=0.008 n=5+5)
LastIndexAnyASCII/16:32-8 198ns ± 0% 197ns ± 0% -0.51% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 313ns ± 0% +1.30% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-8 652ns ± 0% 653ns ± 0% +0.21% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 656ns ± 0% 656ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:4-8 663ns ± 0% 663ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/256:8-8 691ns ± 0% 690ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/256:16-8 719ns ± 0% 715ns ± 0% -0.53% (p=0.000 n=5+4)
LastIndexAnyASCII/256:32-8 779ns ± 0% 780ns ± 0% +0.13% (p=0.029 n=4+4)
LastIndexAnyASCII/256:64-8 890ns ± 0% 894ns ± 0% +0.45% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-8 31.6ns ± 0% 33.5ns ± 0% +6.01% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 33.5ns ± 0% -30.99% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-8 48.6ns ± 0% 33.5ns ± 0% -31.13% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:8-8 89.6ns ± 0% 33.5ns ± 0% -62.56% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 113ns ± 1% 36ns ± 0% -68.47% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 190ns ± 0% 36ns ± 0% -81.26% (p=0.029 n=4+4)
LastIndexAnyUTF8/1:64-8 327ns ± 0% 40ns ± 0% -87.77% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-8 364ns ± 0% 158ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/16:2-8 636ns ± 0% 472ns ± 0% -25.79% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:4-8 630ns ± 0% 472ns ± 0% -25.03% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.28µs ± 0% 0.47µs ± 0% -63.09% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.53µs ± 0% -68.39% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-8 2.88µs ± 0% 0.53µs ± 0% -81.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-8 5.08µs ± 0% 0.57µs ± 0% -88.79% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.41µs ± 0% 2.03µs ± 0% -62.46% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:2-8 9.77µs ± 0% 7.14µs ± 0% -26.97% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.63µs ± 0% 7.14µs ± 0% -25.86% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.0µs ± 0% 7.1µs ± 0% -64.30% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.1µs ± 1% 8.0µs ± 0% -69.40% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 45.6µs ± 1% 8.0µs ± 0% -82.51% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 80.8µs ± 0% 8.6µs ± 0% -89.33% (p=0.016 n=5+4)
pkg:bytes goos:linux goarch:arm64
IndexAnyASCII/1:1-8 26.2ns ± 1% 26.5ns ± 0% +1.30% (p=0.016 n=5+4)
IndexAnyASCII/1:2-8 18.5ns ± 0% 26.5ns ± 0% +43.24% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 21.0ns ± 0% 26.5ns ± 0% +26.38% (p=0.008 n=5+5)
IndexAnyASCII/1:8-8 37.5ns ± 0% 26.5ns ± 0% -29.33% (p=0.000 n=5+4)
IndexAnyASCII/1:16-8 49.6ns ± 0% 26.5ns ± 0% -46.49% (p=0.008 n=5+5)
IndexAnyASCII/1:32-8 73.6ns ± 0% 30.1ns ± 0% -59.16% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 122ns ± 0% 33ns ± 0% -73.23% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.7ns ± 0% 33.4ns ± 0% -54.71% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 79.1ns ± 0% 78.9ns ± 0% -0.30% (p=0.016 n=4+5)
IndexAnyASCII/16:4-8 84.8ns ± 0% 86.1ns ± 0% +1.58% (p=0.016 n=5+4)
IndexAnyASCII/16:8-8 111ns ± 0% 111ns ± 0% ~ (all equal)
IndexAnyASCII/16:16-8 139ns ± 0% 144ns ± 0% +3.60% (p=0.016 n=4+5)
IndexAnyASCII/16:32-8 196ns ± 0% 207ns ± 0% +5.61% (p=0.016 n=5+4)
IndexAnyASCII/16:64-8 311ns ± 0% 320ns ± 0% +2.89% (p=0.016 n=4+5)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 1% -90.35% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 680ns ± 0% 680ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:4-8 686ns ± 0% 687ns ± 0% ~ (p=0.167 n=5+5)
IndexAnyASCII/256:8-8 713ns ± 0% 712ns ± 0% -0.14% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 744ns ± 0% +0.54% (p=0.016 n=5+4)
IndexAnyASCII/256:32-8 797ns ± 0% 808ns ± 0% +1.43% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 912ns ± 0% 921ns ± 0% +0.99% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.5ns ± 0% 26.5ns ± 0% -3.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.5ns ± 0% 26.5ns ± 0% -40.50% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 45.6ns ± 0% 26.5ns ± 0% -41.89% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-8 85.8ns ± 1% 26.5ns ± 0% -69.11% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 26ns ± 0% -76.00% (p=0.016 n=5+4)
IndexAnyUTF8/1:32-8 188ns ± 0% 30ns ± 0% -84.04% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 333ns ± 0% 33ns ± 0% -90.20% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-8 294ns ± 0% 235ns ± 0% -20.07% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 309ns ± 0% -45.12% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 558ns ± 1% 309ns ± 0% -44.60% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.23µs ± 0% 0.31µs ± 0% -74.79% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.62µs ± 2% 0.31µs ± 0% -80.93% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.86µs ± 0% 0.38µs ± 0% -86.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.42µs ± 0% -91.86% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.27µs ± 1% 3.30µs ± 1% -22.75% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-8 8.61µs ± 0% 4.45µs ± 0% -48.31% (p=0.016 n=4+5)
IndexAnyUTF8/256:4-8 8.44µs ± 0% 4.45µs ± 0% -47.23% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-8 19.2µs ± 0% 4.5µs ± 0% -76.78% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-8 25.6µs ± 0% 4.5µs ± 0% -82.63% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.4µs ± 0% 5.5µs ± 0% -87.85% (p=0.016 n=4+5)
IndexAnyUTF8/256:64-8 82.5µs ± 0% 6.2µs ± 0% -92.49% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 26.5ns ± 0% +15.02% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 26.5ns ± 0% +8.16% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-8 27.8ns ± 0% 26.5ns ± 0% -4.68% (p=0.029 n=4+4)
LastIndexAnyASCII/1:8-8 45.1ns ± 1% 26.5ns ± 0% -41.29% (p=0.000 n=5+4)
LastIndexAnyASCII/1:16-8 57.1ns ± 0% 26.5ns ± 0% -53.61% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 81.5ns ± 0% 30.0ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:64-8 129ns ± 0% 32ns ± 0% -74.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.6ns ± 0% 72.1ns ± 0% -0.63% (p=0.000 n=4+5)
LastIndexAnyASCII/16:2-8 77.2ns ± 0% 77.2ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:4-8 83.1ns ± 0% 83.2ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/16:8-8 109ns ± 1% 108ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:16-8 136ns ± 0% 136ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:32-8 195ns ± 0% 197ns ± 0% +0.82% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 309ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:1-8 653ns ± 0% 657ns ± 0% +0.61% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 659ns ± 0% 658ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/256:4-8 664ns ± 0% 663ns ± 0% ~ (p=0.095 n=5+4)
LastIndexAnyASCII/256:8-8 698ns ± 0% 689ns ± 0% -1.29% (p=0.008 n=5+5)
LastIndexAnyASCII/256:16-8 726ns ± 0% 717ns ± 0% -1.24% (p=0.008 n=5+5)
LastIndexAnyASCII/256:32-8 777ns ± 0% 779ns ± 0% ~ (p=0.079 n=5+4)
LastIndexAnyASCII/256:64-8 889ns ± 0% 890ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyUTF8/1:1-8 32.1ns ± 0% 26.5ns ± 0% -17.45% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 26.5ns ± 0% -45.52% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:4-8 49.6ns ± 0% 26.5ns ± 0% -46.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-8 91.9ns ± 0% 26.5ns ± 0% -71.18% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 114ns ± 1% 26ns ± 0% -76.84% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 203ns ± 6% 30ns ± 0% -85.25% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-8 330ns ± 0% 33ns ± 0% -90.14% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:1-8 365ns ± 0% 164ns ± 0% -55.04% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-8 638ns ± 0% 296ns ± 0% -53.58% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-8 634ns ± 0% 296ns ± 0% -53.31% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.30µs ± 0% 0.30µs ± 0% -77.18% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.30µs ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-8 2.90µs ± 0% 0.38µs ± 0% -87.00% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:64-8 5.10µs ± 0% 0.42µs ± 0% -91.78% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.42µs ± 0% 2.12µs ± 0% -60.92% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-8 9.79µs ± 0% 4.26µs ± 0% -56.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.66µs ± 0% 4.26µs ± 0% -55.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.4µs ± 0% 4.3µs ± 0% -79.10% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.0µs ± 1% 4.3µs ± 0% -83.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 46.0µs ± 0% 5.5µs ± 0% -88.09% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 81.1µs ± 0% 6.2µs ± 0% -92.38% (p=0.008 n=5+5)
name old time/op new time/op delta
pkg:strings goos:linux goarch:amd64
IndexAnyASCII/1:1-48 10.0ns ± 0% 13.3ns ± 0% +33.00% (p=0.008 n=5+5)
IndexAnyASCII/1:2-48 11.0ns ± 0% 15.5ns ± 0% +40.55% (p=0.016 n=4+5)
IndexAnyASCII/1:4-48 12.9ns ± 0% 15.4ns ± 0% +19.69% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 18.6ns ± 0% 15.5ns ± 0% -16.45% (p=0.000 n=4+5)
IndexAnyASCII/1:16-48 30.1ns ± 0% 16.9ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/1:32-48 53.1ns ± 0% 18.6ns ± 0% -64.95% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 98.9ns ± 0% 17.4ns ± 0% -82.41% (p=0.000 n=5+4)
IndexAnyASCII/16:1-48 35.0ns ± 0% 14.2ns ± 0% -59.47% (p=0.000 n=5+4)
IndexAnyASCII/16:2-48 35.5ns ± 0% 35.6ns ± 0% ~ (p=0.238 n=5+4)
IndexAnyASCII/16:4-48 40.8ns ± 0% 40.7ns ± 1% ~ (p=0.643 n=5+5)
IndexAnyASCII/16:8-48 50.8ns ± 0% 50.9ns ± 1% ~ (p=1.000 n=4+5)
IndexAnyASCII/16:16-48 64.0ns ± 1% 64.5ns ± 1% ~ (p=0.071 n=5+5)
IndexAnyASCII/16:32-48 98.3ns ± 0% 100.8ns ± 1% +2.52% (p=0.008 n=5+5)
IndexAnyASCII/16:64-48 156ns ± 0% 157ns ± 0% ~ (p=0.238 n=4+5)
IndexAnyASCII/256:1-48 299ns ± 0% 24ns ± 3% -92.12% (p=0.008 n=5+5)
IndexAnyASCII/256:2-48 303ns ± 0% 304ns ± 0% ~ (p=0.762 n=5+5)
IndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.476 n=5+5)
IndexAnyASCII/256:8-48 321ns ± 0% 321ns ± 0% ~ (p=0.429 n=4+5)
IndexAnyASCII/256:16-48 334ns ± 0% 335ns ± 0% ~ (p=0.079 n=5+4)
IndexAnyASCII/256:32-48 367ns ± 0% 365ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/256:64-48 431ns ± 1% 421ns ± 0% -2.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.2ns ± 0% 10.8ns ± 0% -37.21% (p=0.029 n=4+4)
IndexAnyUTF8/1:2-48 26.7ns ± 0% 15.6ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:4-48 28.2ns ± 0% 15.6ns ± 0% -44.68% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-48 48.8ns ± 0% 15.6ns ± 0% -68.03% (p=0.029 n=4+4)
IndexAnyUTF8/1:16-48 58.3ns ± 0% 16.2ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:32-48 103ns ± 0% 18ns ± 0% -82.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 182ns ± 0% 17ns ± 0% -90.53% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 197ns ± 0% 25ns ± 0% -87.34% (p=0.000 n=5+4)
IndexAnyUTF8/16:2-48 348ns ± 0% 163ns ± 0% -53.11% (p=0.000 n=5+4)
IndexAnyUTF8/16:4-48 374ns ± 0% 163ns ± 0% -56.37% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-48 716ns ± 0% 163ns ± 0% -77.22% (p=0.000 n=5+4)
IndexAnyUTF8/16:16-48 859ns ± 0% 175ns ± 0% -79.63% (p=0.000 n=5+4)
IndexAnyUTF8/16:32-48 1.58µs ± 0% 0.20µs ± 0% -87.01% (p=0.029 n=4+4)
IndexAnyUTF8/16:64-48 2.84µs ± 0% 0.19µs ± 1% -93.34% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.61µs ± 0% 0.27µs ± 0% -89.81% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 4.95µs ± 0% 2.23µs ± 0% -54.91% (p=0.016 n=5+4)
IndexAnyUTF8/256:4-48 5.55µs ± 0% 2.23µs ± 0% -59.72% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.2µs ± 0% -79.39% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 13.1µs ± 0% 2.5µs ± 0% -81.21% (p=0.016 n=4+5)
IndexAnyUTF8/256:32-48 24.7µs ± 0% 2.8µs ± 0% -88.49% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-48 45.0µs ± 0% 2.6µs ± 1% -94.23% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-48 13.9ns ± 0% 15.2ns ± 0% +9.35% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-48 14.4ns ± 0% 15.2ns ± 0% +5.56% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-48 16.7ns ± 0% 15.2ns ± 0% -8.98% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-48 24.0ns ± 0% 15.2ns ± 0% -36.67% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-48 35.6ns ± 0% 15.0ns ± 0% -57.82% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-48 68.9ns ± 0% 16.7ns ± 0% -75.75% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 104ns ± 0% 17ns ± 1% -83.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-48 35.0ns ± 0% 35.0ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 35.6ns ± 0% 35.6ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:4-48 41.0ns ± 0% 40.8ns ± 0% -0.49% (p=0.032 n=5+5)
LastIndexAnyASCII/16:8-48 50.9ns ± 0% 50.7ns ± 1% ~ (p=0.397 n=5+5)
LastIndexAnyASCII/16:16-48 64.3ns ± 1% 64.4ns ± 1% ~ (p=1.000 n=4+5)
LastIndexAnyASCII/16:32-48 100ns ± 0% 100ns ± 0% +0.38% (p=0.016 n=4+5)
LastIndexAnyASCII/16:64-48 157ns ± 1% 163ns ± 0% +3.82% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-48 302ns ± 0% 300ns ± 0% -0.53% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 305ns ± 0% 303ns ± 0% -0.66% (p=0.000 n=5+4)
LastIndexAnyASCII/256:4-48 313ns ± 0% 307ns ± 0% -2.04% (p=0.000 n=4+5)
LastIndexAnyASCII/256:8-48 323ns ± 0% 315ns ± 0% -2.48% (p=0.029 n=4+4)
LastIndexAnyASCII/256:16-48 333ns ± 0% 332ns ± 0% -0.30% (p=0.048 n=5+5)
LastIndexAnyASCII/256:32-48 366ns ± 0% 367ns ± 0% ~ (p=0.238 n=4+5)
LastIndexAnyASCII/256:64-48 430ns ± 0% 430ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyUTF8/1:1-48 21.1ns ± 0% 13.9ns ± 0% -34.00% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 29.5ns ± 0% 13.9ns ± 0% -52.95% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 31.6ns ± 0% 13.9ns ± 0% -55.96% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-48 51.1ns ± 0% 13.9ns ± 0% -72.81% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 58.9ns ± 0% 14.6ns ± 0% -75.23% (p=0.016 n=5+4)
LastIndexAnyUTF8/1:32-48 103ns ± 0% 16ns ± 1% -84.12% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 177ns ± 0% 17ns ± 1% -90.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 275ns ± 1% 105ns ± 0% -61.85% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:2-48 406ns ± 0% 216ns ± 0% -46.70% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 458ns ± 0% 216ns ± 0% -52.75% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:8-48 753ns ± 0% 216ns ± 0% -71.31% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:16-48 902ns ± 0% 221ns ± 0% -75.50% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-48 1.57µs ± 0% 0.24µs ± 0% -84.46% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-48 2.77µs ± 0% 0.24µs ± 0% -91.22% (p=0.000 n=5+4)
LastIndexAnyUTF8/256:1-48 4.06µs ± 0% 1.53µs ± 0% -62.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.92µs ± 0% 3.04µs ± 0% -48.55% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:4-48 6.82µs ± 0% 3.04µs ± 0% -55.34% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.5µs ± 0% 3.0µs ± 0% -73.48% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 14.1µs ± 0% 3.1µs ± 0% -77.85% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-48 24.5µs ± 0% 3.5µs ± 0% -85.85% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:64-48 44.0µs ± 0% 3.5µs ± 0% -92.12% (p=0.008 n=5+5)
pkg:bytes goos:linux goarch:amd64
IndexAnyASCII/1:1-48 9.56ns ± 0% 11.00ns ± 0% +15.06% (p=0.016 n=5+4)
IndexAnyASCII/1:2-48 11.0ns ± 0% 10.8ns ± 2% -1.64% (p=0.048 n=5+5)
IndexAnyASCII/1:4-48 13.9ns ± 0% 11.0ns ± 1% -21.15% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 19.6ns ± 0% 10.8ns ± 3% -44.90% (p=0.008 n=5+5)
IndexAnyASCII/1:16-48 31.1ns ± 0% 11.5ns ± 0% -63.02% (p=0.008 n=5+5)
IndexAnyASCII/1:32-48 54.0ns ± 0% 11.8ns ± 0% -78.15% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 100ns ± 0% 13ns ± 0% -86.89% (p=0.008 n=5+5)
IndexAnyASCII/16:1-48 35.5ns ± 0% 14.8ns ± 0% -58.26% (p=0.008 n=5+5)
IndexAnyASCII/16:2-48 36.2ns ± 1% 36.0ns ± 1% ~ (p=0.087 n=5+5)
IndexAnyASCII/16:4-48 40.3ns ± 1% 39.7ns ± 4% ~ (p=0.175 n=4+5)
IndexAnyASCII/16:8-48 48.7ns ± 5% 45.8ns ± 0% -6.02% (p=0.016 n=5+4)
IndexAnyASCII/16:16-48 64.1ns ±11% 62.1ns ± 1% ~ (p=0.143 n=5+5)
IndexAnyASCII/16:32-48 97.9ns ± 1% 98.3ns ± 1% ~ (p=0.294 n=5+5)
IndexAnyASCII/16:64-48 163ns ± 0% 157ns ± 0% -3.68% (p=0.008 n=5+5)
IndexAnyASCII/256:1-48 389ns ± 0% 25ns ± 0% -93.65% (p=0.000 n=5+4)
IndexAnyASCII/256:2-48 391ns ± 0% 307ns ± 0% -21.48% (p=0.000 n=5+4)
IndexAnyASCII/256:4-48 394ns ± 0% 323ns ± 0% -17.92% (p=0.008 n=5+5)
IndexAnyASCII/256:8-48 402ns ± 0% 323ns ± 0% -19.51% (p=0.008 n=5+5)
IndexAnyASCII/256:16-48 414ns ± 0% 334ns ± 0% -19.32% (p=0.016 n=4+5)
IndexAnyASCII/256:32-48 446ns ± 0% 367ns ± 0% -17.75% (p=0.016 n=5+4)
IndexAnyASCII/256:64-48 511ns ± 0% 424ns ± 0% -17.02% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.4ns ± 0% 11.0ns ± 0% -36.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-48 27.3ns ± 1% 11.0ns ± 0% -59.74% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-48 28.7ns ± 0% 11.0ns ± 0% -61.73% (p=0.008 n=5+5)
IndexAnyUTF8/1:8-48 49.2ns ± 0% 11.0ns ± 0% -77.66% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-48 56.0ns ± 0% 11.5ns ± 0% -79.46% (p=0.000 n=5+4)
IndexAnyUTF8/1:32-48 102ns ± 0% 12ns ± 0% -88.24% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 177ns ± 0% 13ns ± 0% -92.51% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 212ns ± 0% 112ns ± 0% -47.17% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-48 356ns ± 0% 159ns ± 1% -55.28% (p=0.000 n=4+5)
IndexAnyUTF8/16:4-48 372ns ± 0% 158ns ± 0% -57.47% (p=0.008 n=5+5)
IndexAnyUTF8/16:8-48 712ns ± 0% 159ns ± 1% -77.70% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-48 829ns ± 0% 129ns ± 0% -84.44% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-48 1.55µs ± 0% 0.16µs ± 0% -89.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-48 2.77µs ± 0% 0.14µs ± 0% -94.94% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.85µs ± 0% 1.63µs ± 1% -42.74% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 5.14µs ± 1% 2.03µs ± 0% -60.51% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-48 5.56µs ± 0% 2.03µs ± 0% -63.52% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.0µs ± 0% -81.22% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 12.9µs ± 0% 1.9µs ± 0% -85.55% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-48 24.2µs ± 0% 2.1µs ± 0% -91.29% (p=0.016 n=5+4)
IndexAnyUTF8/256:64-48 43.7µs ± 0% 2.0µs ± 0% -95.32% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-48 13.7ns ± 1% 12.8ns ± 0% -6.57% (p=0.016 n=5+4)
LastIndexAnyASCII/1:2-48 14.7ns ± 0% 12.7ns ± 1% -13.33% (p=0.000 n=4+5)
LastIndexAnyASCII/1:4-48 16.9ns ± 0% 12.7ns ± 1% -24.73% (p=0.000 n=4+5)
LastIndexAnyASCII/1:8-48 20.5ns ± 0% 12.7ns ± 0% -37.85% (p=0.000 n=4+5)
LastIndexAnyASCII/1:16-48 28.0ns ± 0% 11.7ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:32-48 69.8ns ± 0% 12.4ns ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 73.8ns ± 0% 13.3ns ± 0% -82.03% (p=0.000 n=4+5)
LastIndexAnyASCII/16:1-48 35.5ns ± 0% 35.5ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 36.0ns ± 0% 36.1ns ± 0% +0.28% (p=0.016 n=4+5)
LastIndexAnyASCII/16:4-48 40.3ns ± 2% 40.0ns ± 6% ~ (p=0.651 n=5+5)
LastIndexAnyASCII/16:8-48 50.3ns ± 0% 50.2ns ± 9% ~ (p=0.175 n=4+5)
LastIndexAnyASCII/16:16-48 62.4ns ± 4% 64.4ns ± 0% +3.28% (p=0.016 n=5+4)
LastIndexAnyASCII/16:32-48 98.9ns ± 0% 98.4ns ± 0% -0.53% (p=0.016 n=5+4)
LastIndexAnyASCII/16:64-48 160ns ± 1% 161ns ± 1% ~ (p=0.325 n=5+5)
LastIndexAnyASCII/256:1-48 300ns ± 0% 301ns ± 0% +0.33% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 304ns ± 0% 304ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.556 n=4+5)
LastIndexAnyASCII/256:8-48 320ns ± 0% 321ns ± 0% ~ (p=0.143 n=5+5)
LastIndexAnyASCII/256:16-48 333ns ± 0% 335ns ± 0% +0.60% (p=0.029 n=4+4)
LastIndexAnyASCII/256:32-48 367ns ± 0% 366ns ± 0% ~ (p=0.095 n=4+5)
LastIndexAnyASCII/256:64-48 431ns ± 0% 424ns ± 0% -1.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-48 19.7ns ± 1% 11.9ns ± 0% -39.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 27.6ns ± 1% 11.9ns ± 0% -56.82% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 29.9ns ± 0% 11.9ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/1:8-48 48.7ns ± 0% 11.9ns ± 0% -75.54% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 57.8ns ± 0% 11.4ns ± 0% -80.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:32-48 94.7ns ± 0% 12.2ns ± 0% -87.07% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 163ns ± 0% 13ns ± 1% -91.93% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 258ns ± 0% 88ns ± 0% -65.76% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-48 400ns ± 0% 162ns ± 0% -59.38% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 415ns ± 0% 162ns ± 0% -60.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-48 737ns ± 0% 162ns ± 0% -78.02% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:16-48 882ns ± 0% 128ns ± 0% -85.49% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-48 1.47µs ± 0% 0.16µs ± 0% -89.29% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:64-48 2.56µs ± 0% 0.14µs ± 0% -94.41% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:1-48 3.60µs ± 0% 1.23µs ± 0% -65.67% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.78µs ± 0% 2.18µs ± 0% -62.32% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-48 6.26µs ± 0% 2.18µs ± 0% -65.15% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.2µs ± 0% 2.2µs ± 0% -80.53% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 13.5µs ± 0% 1.9µs ± 0% -86.02% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:32-48 23.0µs ± 0% 2.1µs ± 0% -90.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-48 40.5µs ± 0% 2.1µs ± 0% -94.73% (p=0.008 n=5+5)
Change-Id: Ie05e306f8b184b989701868cb161ce8b3f18203b
Reviewed-on: https://go-review.googlesource.com/c/go/+/156998
Run-TryBot: eric fang <eric.fang@arm.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-12-23 02:15:44 +00:00
|
|
|
|
{"0123456\xcf\x80abc", "\xcfb\x80", 10},
|
2010-11-12 12:47:50 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-03-26 13:05:04 -07:00
|
|
|
|
// Execute f on each test case. funcName should be the name of f; it's used
|
|
|
|
|
|
// in failure reports.
|
|
|
|
|
|
func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) {
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
|
|
a := []byte(test.a)
|
|
|
|
|
|
b := []byte(test.b)
|
|
|
|
|
|
actual := f(a, b)
|
|
|
|
|
|
if actual != test.i {
|
|
|
|
|
|
t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i)
|
2009-11-18 19:23:08 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-11-21 14:38:25 +08:00
|
|
|
|
var allocTests = []struct {
|
|
|
|
|
|
a []byte
|
|
|
|
|
|
b []byte
|
|
|
|
|
|
i int
|
|
|
|
|
|
}{
|
|
|
|
|
|
// case for function Index.
|
|
|
|
|
|
{[]byte("000000000000000000000000000000000000000000000000000000000000000000000001"), []byte("0000000000000000000000000000000000000000000000000000000000000000001"), 5},
|
|
|
|
|
|
// case for function LastIndex.
|
|
|
|
|
|
{[]byte("000000000000000000000000000000000000000000000000000000000000000010000"), []byte("00000000000000000000000000000000000000000000000000000000000001"), 3},
|
|
|
|
|
|
}
|
|
|
|
|
|
allocs := testing.AllocsPerRun(100, func() {
|
|
|
|
|
|
if i := Index(allocTests[1].a, allocTests[1].b); i != allocTests[1].i {
|
|
|
|
|
|
t.Errorf("Index([]byte(%q), []byte(%q)) = %v; want %v", allocTests[1].a, allocTests[1].b, i, allocTests[1].i)
|
|
|
|
|
|
}
|
|
|
|
|
|
if i := LastIndex(allocTests[0].a, allocTests[0].b); i != allocTests[0].i {
|
|
|
|
|
|
t.Errorf("LastIndex([]byte(%q), []byte(%q)) = %v; want %v", allocTests[0].a, allocTests[0].b, i, allocTests[0].i)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
if allocs != 0 {
|
|
|
|
|
|
t.Errorf("expected no allocations, got %f", allocs)
|
|
|
|
|
|
}
|
2009-11-18 19:23:08 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-11-12 12:47:50 -08:00
|
|
|
|
func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) {
|
|
|
|
|
|
for _, test := range testCases {
|
2010-05-03 10:59:00 -07:00
|
|
|
|
a := []byte(test.a)
|
2010-11-12 12:47:50 -08:00
|
|
|
|
actual := f(a, test.b)
|
2010-05-03 10:59:00 -07:00
|
|
|
|
if actual != test.i {
|
2010-11-12 12:47:50 -08:00
|
|
|
|
t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, test.b, actual, test.i)
|
2010-05-03 10:59:00 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-03-26 13:05:04 -07:00
|
|
|
|
|
2010-11-12 12:47:50 -08:00
|
|
|
|
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
|
|
|
|
|
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
|
|
|
|
|
func TestIndexAny(t *testing.T) { runIndexAnyTests(t, IndexAny, "IndexAny", indexAnyTests) }
|
|
|
|
|
|
func TestLastIndexAny(t *testing.T) {
|
|
|
|
|
|
runIndexAnyTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-11-18 19:23:08 -08:00
|
|
|
|
func TestIndexByte(t *testing.T) {
|
2010-03-26 13:05:04 -07:00
|
|
|
|
for _, tt := range indexTests {
|
2009-11-18 19:23:08 -08:00
|
|
|
|
if len(tt.b) != 1 {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2010-02-25 16:01:29 -08:00
|
|
|
|
a := []byte(tt.a)
|
2009-12-15 15:33:31 -08:00
|
|
|
|
b := tt.b[0]
|
|
|
|
|
|
pos := IndexByte(a, b)
|
2009-11-18 19:23:08 -08:00
|
|
|
|
if pos != tt.i {
|
|
|
|
|
|
t.Errorf(`IndexByte(%q, '%c') = %v`, tt.a, b, pos)
|
|
|
|
|
|
}
|
2009-12-15 15:33:31 -08:00
|
|
|
|
posp := IndexBytePortable(a, b)
|
2009-12-04 10:23:43 -08:00
|
|
|
|
if posp != tt.i {
|
|
|
|
|
|
t.Errorf(`indexBytePortable(%q, '%c') = %v`, tt.a, b, posp)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-04-29 20:45:55 +03:00
|
|
|
|
func TestLastIndexByte(t *testing.T) {
|
|
|
|
|
|
testCases := []BinOpTest{
|
|
|
|
|
|
{"", "q", -1},
|
|
|
|
|
|
{"abcdef", "q", -1},
|
|
|
|
|
|
{"abcdefabcdef", "a", len("abcdef")}, // something in the middle
|
|
|
|
|
|
{"abcdefabcdef", "f", len("abcdefabcde")}, // last byte
|
|
|
|
|
|
{"zabcdefabcdef", "z", 0}, // first byte
|
|
|
|
|
|
{"a☺b☻c☹d", "b", len("a☺")}, // non-ascii
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
|
|
actual := LastIndexByte([]byte(test.a), test.b[0])
|
|
|
|
|
|
if actual != test.i {
|
|
|
|
|
|
t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.a, test.b[0], actual, test.i)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-11-08 17:33:53 -08:00
|
|
|
|
// test a larger buffer with different sizes and alignments
|
|
|
|
|
|
func TestIndexByteBig(t *testing.T) {
|
2011-03-25 16:31:10 -07:00
|
|
|
|
var n = 1024
|
|
|
|
|
|
if testing.Short() {
|
|
|
|
|
|
n = 128
|
|
|
|
|
|
}
|
2010-11-08 17:33:53 -08:00
|
|
|
|
b := make([]byte, n)
|
|
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
|
|
// different start alignments
|
|
|
|
|
|
b1 := b[i:]
|
|
|
|
|
|
for j := 0; j < len(b1); j++ {
|
|
|
|
|
|
b1[j] = 'x'
|
|
|
|
|
|
pos := IndexByte(b1, 'x')
|
|
|
|
|
|
if pos != j {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
|
|
|
|
|
|
}
|
|
|
|
|
|
b1[j] = 0
|
|
|
|
|
|
pos = IndexByte(b1, 'x')
|
|
|
|
|
|
if pos != -1 {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// different end alignments
|
|
|
|
|
|
b1 = b[:i]
|
|
|
|
|
|
for j := 0; j < len(b1); j++ {
|
|
|
|
|
|
b1[j] = 'x'
|
|
|
|
|
|
pos := IndexByte(b1, 'x')
|
|
|
|
|
|
if pos != j {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
|
|
|
|
|
|
}
|
|
|
|
|
|
b1[j] = 0
|
|
|
|
|
|
pos = IndexByte(b1, 'x')
|
|
|
|
|
|
if pos != -1 {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// different start and end alignments
|
|
|
|
|
|
b1 = b[i/2 : n-(i+1)/2]
|
|
|
|
|
|
for j := 0; j < len(b1); j++ {
|
|
|
|
|
|
b1[j] = 'x'
|
|
|
|
|
|
pos := IndexByte(b1, 'x')
|
|
|
|
|
|
if pos != j {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
|
|
|
|
|
|
}
|
|
|
|
|
|
b1[j] = 0
|
|
|
|
|
|
pos = IndexByte(b1, 'x')
|
|
|
|
|
|
if pos != -1 {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-01-15 18:17:09 -08:00
|
|
|
|
// test a small index across all page offsets
|
|
|
|
|
|
func TestIndexByteSmall(t *testing.T) {
|
|
|
|
|
|
b := make([]byte, 5015) // bigger than a page
|
|
|
|
|
|
// Make sure we find the correct byte even when straddling a page.
|
|
|
|
|
|
for i := 0; i <= len(b)-15; i++ {
|
|
|
|
|
|
for j := 0; j < 15; j++ {
|
|
|
|
|
|
b[i+j] = byte(100 + j)
|
|
|
|
|
|
}
|
|
|
|
|
|
for j := 0; j < 15; j++ {
|
|
|
|
|
|
p := IndexByte(b[i:i+15], byte(100+j))
|
|
|
|
|
|
if p != j {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, %d) = %d", b[i:i+15], 100+j, p)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for j := 0; j < 15; j++ {
|
|
|
|
|
|
b[i+j] = 0
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// Make sure matches outside the slice never trigger.
|
|
|
|
|
|
for i := 0; i <= len(b)-15; i++ {
|
|
|
|
|
|
for j := 0; j < 15; j++ {
|
|
|
|
|
|
b[i+j] = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
for j := 0; j < 15; j++ {
|
|
|
|
|
|
p := IndexByte(b[i:i+15], byte(0))
|
|
|
|
|
|
if p != -1 {
|
|
|
|
|
|
t.Errorf("IndexByte(%q, %d) = %d", b[i:i+15], 0, p)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for j := 0; j < 15; j++ {
|
|
|
|
|
|
b[i+j] = 0
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-08-05 23:11:06 +10:00
|
|
|
|
func TestIndexRune(t *testing.T) {
|
2016-10-26 14:18:37 -07:00
|
|
|
|
tests := []struct {
|
|
|
|
|
|
in string
|
|
|
|
|
|
rune rune
|
|
|
|
|
|
want int
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"", 'a', -1},
|
|
|
|
|
|
{"", '☺', -1},
|
|
|
|
|
|
{"foo", '☹', -1},
|
|
|
|
|
|
{"foo", 'o', 1},
|
|
|
|
|
|
{"foo☺bar", '☺', 3},
|
|
|
|
|
|
{"foo☺☻☹bar", '☹', 9},
|
|
|
|
|
|
{"a A x", 'A', 2},
|
|
|
|
|
|
{"some_text=some_value", '=', 9},
|
|
|
|
|
|
{"☺a", 'a', 3},
|
|
|
|
|
|
{"a☻☺b", '☺', 4},
|
2023-11-02 00:18:59 -04:00
|
|
|
|
{"𠀳𠀗𠀾𠁄𠀧𠁆𠁂𠀫𠀖𠀪𠀲𠀴𠁀𠀨𠀿", '𠀿', 56},
|
|
|
|
|
|
|
|
|
|
|
|
// 2 bytes
|
|
|
|
|
|
{"ӆ", 'ӆ', 0},
|
|
|
|
|
|
{"a", 'ӆ', -1},
|
|
|
|
|
|
{" ӆ", 'ӆ', 2},
|
|
|
|
|
|
{" a", 'ӆ', -1},
|
|
|
|
|
|
{strings.Repeat("ц", 64) + "ӆ", 'ӆ', 128}, // test cutover
|
|
|
|
|
|
{strings.Repeat("ц", 64), 'ӆ', -1},
|
|
|
|
|
|
|
|
|
|
|
|
// 3 bytes
|
|
|
|
|
|
{"Ꚁ", 'Ꚁ', 0},
|
|
|
|
|
|
{"a", 'Ꚁ', -1},
|
|
|
|
|
|
{" Ꚁ", 'Ꚁ', 2},
|
|
|
|
|
|
{" a", 'Ꚁ', -1},
|
|
|
|
|
|
{strings.Repeat("Ꙁ", 64) + "Ꚁ", 'Ꚁ', 192}, // test cutover
|
|
|
|
|
|
{strings.Repeat("Ꙁ", 64) + "Ꚁ", '䚀', -1}, // 'Ꚁ' and '䚀' share the same last two bytes
|
|
|
|
|
|
|
|
|
|
|
|
// 4 bytes
|
|
|
|
|
|
{"𡌀", '𡌀', 0},
|
|
|
|
|
|
{"a", '𡌀', -1},
|
|
|
|
|
|
{" 𡌀", '𡌀', 2},
|
|
|
|
|
|
{" a", '𡌀', -1},
|
|
|
|
|
|
{strings.Repeat("𡋀", 64) + "𡌀", '𡌀', 256}, // test cutover
|
|
|
|
|
|
{strings.Repeat("𡋀", 64) + "𡌀", '𣌀', -1}, // '𡌀' and '𣌀' share the same last two bytes
|
2016-10-26 14:18:37 -07:00
|
|
|
|
|
|
|
|
|
|
// RuneError should match any invalid UTF-8 byte sequence.
|
|
|
|
|
|
{"<22>", '<27>', 0},
|
|
|
|
|
|
{"\xff", '<27>', 0},
|
|
|
|
|
|
{"☻x<E298BB>", '<27>', len("☻x")},
|
|
|
|
|
|
{"☻x\xe2\x98", '<27>', len("☻x")},
|
|
|
|
|
|
{"☻x\xe2\x98<39>", '<27>', len("☻x")},
|
|
|
|
|
|
{"☻x\xe2\x98x", '<27>', len("☻x")},
|
|
|
|
|
|
|
|
|
|
|
|
// Invalid rune values should never match.
|
|
|
|
|
|
{"a☺b☻c☹d\xe2\x98<39>\xff<66>\xed\xa0\x80", -1, -1},
|
|
|
|
|
|
{"a☺b☻c☹d\xe2\x98<39>\xff<66>\xed\xa0\x80", 0xD800, -1}, // Surrogate pair
|
|
|
|
|
|
{"a☺b☻c☹d\xe2\x98<39>\xff<66>\xed\xa0\x80", utf8.MaxRune + 1, -1},
|
2023-11-02 00:18:59 -04:00
|
|
|
|
|
2024-08-19 00:07:37 +03:00
|
|
|
|
// Test the cutover to bytealg.Index when it is triggered in
|
2023-11-02 00:18:59 -04:00
|
|
|
|
// the middle of rune that contains consecutive runs of equal bytes.
|
|
|
|
|
|
{"aaaaaKKKK\U000bc104", '\U000bc104', 17}, // cutover: (n + 16) / 8
|
|
|
|
|
|
{"aaaaaKKKK鄄", '鄄', 17},
|
|
|
|
|
|
{"aaKKKKKa\U000bc104", '\U000bc104', 18}, // cutover: 4 + n>>4
|
|
|
|
|
|
{"aaKKKKKa鄄", '鄄', 18},
|
2016-10-26 14:18:37 -07:00
|
|
|
|
}
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
|
if got := IndexRune([]byte(tt.in), tt.rune); got != tt.want {
|
|
|
|
|
|
t.Errorf("IndexRune(%q, %d) = %v; want %v", tt.in, tt.rune, got, tt.want)
|
2010-08-05 23:11:06 +10:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-09-06 08:09:27 +09:00
|
|
|
|
|
|
|
|
|
|
haystack := []byte("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 {
|
2016-10-26 14:18:37 -07:00
|
|
|
|
t.Errorf("expected no allocations, got %f", allocs)
|
2016-09-06 08:09:27 +09:00
|
|
|
|
}
|
2010-08-05 23:11:06 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-19 12:18:08 +01:00
|
|
|
|
// test count of a single byte across page offsets
|
|
|
|
|
|
func TestCountByte(t *testing.T) {
|
|
|
|
|
|
b := make([]byte, 5015) // bigger than a page
|
|
|
|
|
|
windows := []int{1, 2, 3, 4, 15, 16, 17, 31, 32, 33, 63, 64, 65, 128}
|
|
|
|
|
|
testCountWindow := func(i, window int) {
|
|
|
|
|
|
for j := 0; j < window; j++ {
|
|
|
|
|
|
b[i+j] = byte(100)
|
|
|
|
|
|
p := Count(b[i:i+window], []byte{100})
|
|
|
|
|
|
if p != j+1 {
|
|
|
|
|
|
t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
maxWnd := windows[len(windows)-1]
|
|
|
|
|
|
|
|
|
|
|
|
for i := 0; i <= 2*maxWnd; i++ {
|
|
|
|
|
|
for _, window := range windows {
|
|
|
|
|
|
if window > len(b[i:]) {
|
|
|
|
|
|
window = len(b[i:])
|
|
|
|
|
|
}
|
|
|
|
|
|
testCountWindow(i, window)
|
|
|
|
|
|
for j := 0; j < window; j++ {
|
|
|
|
|
|
b[i+j] = byte(0)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for i := 4096 - (maxWnd + 1); i < len(b); i++ {
|
|
|
|
|
|
for _, window := range windows {
|
|
|
|
|
|
if window > len(b[i:]) {
|
|
|
|
|
|
window = len(b[i:])
|
|
|
|
|
|
}
|
|
|
|
|
|
testCountWindow(i, window)
|
|
|
|
|
|
for j := 0; j < window; j++ {
|
|
|
|
|
|
b[i+j] = byte(0)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure we don't count bytes outside our window
|
|
|
|
|
|
func TestCountByteNoMatch(t *testing.T) {
|
|
|
|
|
|
b := make([]byte, 5015)
|
|
|
|
|
|
windows := []int{1, 2, 3, 4, 15, 16, 17, 31, 32, 33, 63, 64, 65, 128}
|
|
|
|
|
|
for i := 0; i <= len(b); i++ {
|
|
|
|
|
|
for _, window := range windows {
|
|
|
|
|
|
if window > len(b[i:]) {
|
|
|
|
|
|
window = len(b[i:])
|
|
|
|
|
|
}
|
|
|
|
|
|
// Fill the window with non-match
|
|
|
|
|
|
for j := 0; j < window; j++ {
|
|
|
|
|
|
b[i+j] = byte(100)
|
|
|
|
|
|
}
|
|
|
|
|
|
// Try to find something that doesn't exist
|
|
|
|
|
|
p := Count(b[i:i+window], []byte{0})
|
|
|
|
|
|
if p != 0 {
|
|
|
|
|
|
t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
|
|
|
|
|
|
}
|
|
|
|
|
|
for j := 0; j < window; j++ {
|
|
|
|
|
|
b[i+j] = byte(0)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-12-07 15:09:56 -05:00
|
|
|
|
var bmbuf []byte
|
2009-12-04 10:23:43 -08:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func valName(x int) string {
|
|
|
|
|
|
if s := x >> 20; s<<20 == x {
|
|
|
|
|
|
return fmt.Sprintf("%dM", s)
|
|
|
|
|
|
}
|
|
|
|
|
|
if s := x >> 10; s<<10 == x {
|
|
|
|
|
|
return fmt.Sprintf("%dK", s)
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2016-05-26 10:54:25 +02:00
|
|
|
|
return fmt.Sprint(x)
|
2009-12-04 10:23:43 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func benchBytes(b *testing.B, sizes []int, f func(b *testing.B, n int)) {
|
|
|
|
|
|
for _, n := range sizes {
|
2016-09-14 18:03:26 +00:00
|
|
|
|
if isRaceBuilder && n > 4<<10 {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2016-05-26 10:54:25 +02:00
|
|
|
|
b.Run(valName(n), func(b *testing.B) {
|
|
|
|
|
|
if len(bmbuf) < n {
|
|
|
|
|
|
bmbuf = make([]byte, n)
|
|
|
|
|
|
}
|
|
|
|
|
|
b.SetBytes(int64(n))
|
|
|
|
|
|
f(b, n)
|
|
|
|
|
|
})
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2009-12-04 10:23:43 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
var indexSizes = []int{10, 32, 4 << 10, 4 << 20, 64 << 20}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
|
2016-09-14 18:03:26 +00:00
|
|
|
|
var isRaceBuilder = strings.HasSuffix(testenv.Builder(), "-race")
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkIndexByte(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexByte(IndexByte))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkIndexBytePortable(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexByte(IndexBytePortable))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func bmIndexByte(index func([]byte, byte) int) func(b *testing.B, n int) {
|
|
|
|
|
|
return func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
buf[n-1] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := index(buf, 'x')
|
|
|
|
|
|
if j != n-1 {
|
|
|
|
|
|
b.Fatal("bad index", j)
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2016-05-26 10:54:25 +02:00
|
|
|
|
buf[n-1] = '\x00'
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2009-12-04 10:23:43 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-06 08:09:27 +09:00
|
|
|
|
func BenchmarkIndexRune(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexRune(IndexRune))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkIndexRuneASCII(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexRuneASCII(IndexRune))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-02 00:18:59 -04:00
|
|
|
|
func BenchmarkIndexRuneUnicode(b *testing.B) {
|
|
|
|
|
|
b.Run("Latin", func(b *testing.B) {
|
|
|
|
|
|
// Latin is mostly 1, 2, 3 byte runes.
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexRuneUnicode(unicode.Latin, 'é'))
|
|
|
|
|
|
})
|
|
|
|
|
|
b.Run("Cyrillic", func(b *testing.B) {
|
|
|
|
|
|
// Cyrillic is mostly 2 and 3 byte runes.
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexRuneUnicode(unicode.Cyrillic, 'Ꙁ'))
|
|
|
|
|
|
})
|
|
|
|
|
|
b.Run("Han", func(b *testing.B) {
|
|
|
|
|
|
// Han consists only of 3 and 4 byte runes.
|
|
|
|
|
|
benchBytes(b, indexSizes, bmIndexRuneUnicode(unicode.Han, '𠀿'))
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-06 08:09:27 +09:00
|
|
|
|
func bmIndexRuneASCII(index func([]byte, rune) int) func(b *testing.B, n int) {
|
|
|
|
|
|
return func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
buf[n-1] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := index(buf, 'x')
|
|
|
|
|
|
if j != n-1 {
|
|
|
|
|
|
b.Fatal("bad index", j)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
buf[n-1] = '\x00'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func bmIndexRune(index func([]byte, rune) int) func(b *testing.B, n int) {
|
|
|
|
|
|
return func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
utf8.EncodeRune(buf[n-3:], '世')
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := index(buf, '世')
|
|
|
|
|
|
if j != n-3 {
|
|
|
|
|
|
b.Fatal("bad index", j)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
buf[n-3] = '\x00'
|
|
|
|
|
|
buf[n-2] = '\x00'
|
|
|
|
|
|
buf[n-1] = '\x00'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-02 00:18:59 -04:00
|
|
|
|
func bmIndexRuneUnicode(rt *unicode.RangeTable, needle rune) func(b *testing.B, n int) {
|
|
|
|
|
|
var rs []rune
|
|
|
|
|
|
for _, r16 := range rt.R16 {
|
|
|
|
|
|
for r := rune(r16.Lo); r <= rune(r16.Hi); r += rune(r16.Stride) {
|
|
|
|
|
|
if r != needle {
|
2025-07-28 11:36:17 +00:00
|
|
|
|
rs = append(rs, r)
|
2023-11-02 00:18:59 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, r32 := range rt.R32 {
|
|
|
|
|
|
for r := rune(r32.Lo); r <= rune(r32.Hi); r += rune(r32.Stride) {
|
|
|
|
|
|
if r != needle {
|
2025-07-28 11:36:17 +00:00
|
|
|
|
rs = append(rs, r)
|
2023-11-02 00:18:59 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// Shuffle the runes so that they are not in descending order.
|
|
|
|
|
|
// The sort is deterministic since this is used for benchmarks,
|
|
|
|
|
|
// which need to be repeatable.
|
|
|
|
|
|
rr := rand.New(rand.NewSource(1))
|
|
|
|
|
|
rr.Shuffle(len(rs), func(i, j int) {
|
|
|
|
|
|
rs[i], rs[j] = rs[j], rs[i]
|
|
|
|
|
|
})
|
|
|
|
|
|
uchars := string(rs)
|
|
|
|
|
|
|
|
|
|
|
|
return func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
o := copy(buf, uchars)
|
|
|
|
|
|
for o < len(buf) {
|
|
|
|
|
|
o += copy(buf[o:], uchars)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Make space for the needle rune at the end of buf.
|
|
|
|
|
|
m := utf8.RuneLen(needle)
|
|
|
|
|
|
for o := m; o > 0; {
|
|
|
|
|
|
_, sz := utf8.DecodeLastRune(buf)
|
|
|
|
|
|
copy(buf[len(buf)-sz:], "\x00\x00\x00\x00")
|
|
|
|
|
|
buf = buf[:len(buf)-sz]
|
|
|
|
|
|
o -= sz
|
|
|
|
|
|
}
|
|
|
|
|
|
buf = utf8.AppendRune(buf[:n-m], needle)
|
|
|
|
|
|
|
|
|
|
|
|
n -= m // adjust for rune len
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := IndexRune(buf, needle)
|
|
|
|
|
|
if j != n {
|
|
|
|
|
|
b.Fatal("bad index", j)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for i := range buf {
|
|
|
|
|
|
buf[i] = '\x00'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkEqual(b *testing.B) {
|
|
|
|
|
|
b.Run("0", func(b *testing.B) {
|
|
|
|
|
|
var buf [4]byte
|
|
|
|
|
|
buf1 := buf[0:0]
|
|
|
|
|
|
buf2 := buf[1:1]
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
eq := Equal(buf1, buf2)
|
|
|
|
|
|
if !eq {
|
|
|
|
|
|
b.Fatal("bad equal")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2009-12-04 10:23:43 -08:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
sizes := []int{1, 6, 9, 15, 16, 20, 32, 4 << 10, 4 << 20, 64 << 20}
|
2023-11-28 18:42:43 +00:00
|
|
|
|
|
|
|
|
|
|
b.Run("same", func(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, sizes, bmEqual(func(a, b []byte) bool { return Equal(a, a) }))
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
benchBytes(b, sizes, bmEqual(Equal))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func bmEqual(equal func([]byte, []byte) bool) func(b *testing.B, n int) {
|
|
|
|
|
|
return func(b *testing.B, n int) {
|
|
|
|
|
|
if len(bmbuf) < 2*n {
|
|
|
|
|
|
bmbuf = make([]byte, 2*n)
|
|
|
|
|
|
}
|
|
|
|
|
|
buf1 := bmbuf[0:n]
|
|
|
|
|
|
buf2 := bmbuf[n : 2*n]
|
|
|
|
|
|
buf1[n-1] = 'x'
|
|
|
|
|
|
buf2[n-1] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
eq := equal(buf1, buf2)
|
|
|
|
|
|
if !eq {
|
|
|
|
|
|
b.Fatal("bad equal")
|
|
|
|
|
|
}
|
2009-12-04 10:23:43 -08:00
|
|
|
|
}
|
2016-05-26 10:54:25 +02:00
|
|
|
|
buf1[n-1] = '\x00'
|
|
|
|
|
|
buf2[n-1] = '\x00'
|
2009-11-18 19:23:08 -08:00
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2023-06-02 13:13:29 +02:00
|
|
|
|
|
|
|
|
|
|
func BenchmarkEqualBothUnaligned(b *testing.B) {
|
|
|
|
|
|
sizes := []int{64, 4 << 10}
|
|
|
|
|
|
if !isRaceBuilder {
|
|
|
|
|
|
sizes = append(sizes, []int{4 << 20, 64 << 20}...)
|
|
|
|
|
|
}
|
|
|
|
|
|
maxSize := 2 * (sizes[len(sizes)-1] + 8)
|
|
|
|
|
|
if len(bmbuf) < maxSize {
|
|
|
|
|
|
bmbuf = make([]byte, maxSize)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, n := range sizes {
|
|
|
|
|
|
for _, off := range []int{0, 1, 4, 7} {
|
|
|
|
|
|
buf1 := bmbuf[off : off+n]
|
|
|
|
|
|
buf2Start := (len(bmbuf) / 2) + off
|
|
|
|
|
|
buf2 := bmbuf[buf2Start : buf2Start+n]
|
|
|
|
|
|
buf1[n-1] = 'x'
|
|
|
|
|
|
buf2[n-1] = 'x'
|
|
|
|
|
|
b.Run(fmt.Sprint(n, off), func(b *testing.B) {
|
|
|
|
|
|
b.SetBytes(int64(n))
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
eq := Equal(buf1, buf2)
|
|
|
|
|
|
if !eq {
|
|
|
|
|
|
b.Fatal("bad equal")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
buf1[n-1] = '\x00'
|
|
|
|
|
|
buf2[n-1] = '\x00'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkIndex(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
buf[n-1] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := Index(buf, buf[n-7:])
|
|
|
|
|
|
if j != n-7 {
|
|
|
|
|
|
b.Fatal("bad index", j)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
buf[n-1] = '\x00'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkIndexEasy(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
buf[n-1] = 'x'
|
|
|
|
|
|
buf[n-7] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := Index(buf, buf[n-7:])
|
|
|
|
|
|
if j != n-7 {
|
|
|
|
|
|
b.Fatal("bad index", j)
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2016-05-26 10:54:25 +02:00
|
|
|
|
buf[n-1] = '\x00'
|
|
|
|
|
|
buf[n-7] = '\x00'
|
|
|
|
|
|
})
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkCount(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
buf[n-1] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := Count(buf, buf[n-7:])
|
|
|
|
|
|
if j != 1 {
|
|
|
|
|
|
b.Fatal("bad count", j)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
buf[n-1] = '\x00'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkCountEasy(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
buf[n-1] = 'x'
|
|
|
|
|
|
buf[n-7] = 'x'
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := Count(buf, buf[n-7:])
|
|
|
|
|
|
if j != 1 {
|
|
|
|
|
|
b.Fatal("bad count", j)
|
|
|
|
|
|
}
|
2011-12-07 15:09:56 -05:00
|
|
|
|
}
|
2016-05-26 10:54:25 +02:00
|
|
|
|
buf[n-1] = '\x00'
|
|
|
|
|
|
buf[n-7] = '\x00'
|
|
|
|
|
|
})
|
2009-11-18 19:23:08 -08:00
|
|
|
|
}
|
2009-06-04 14:41:31 -07:00
|
|
|
|
|
2017-03-19 12:18:08 +01:00
|
|
|
|
func BenchmarkCountSingle(b *testing.B) {
|
|
|
|
|
|
benchBytes(b, indexSizes, func(b *testing.B, n int) {
|
|
|
|
|
|
buf := bmbuf[0:n]
|
|
|
|
|
|
step := 8
|
|
|
|
|
|
for i := 0; i < len(buf); i += step {
|
|
|
|
|
|
buf[i] = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
expect := (len(buf) + (step - 1)) / step
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
j := Count(buf, []byte{1})
|
|
|
|
|
|
if j != expect {
|
|
|
|
|
|
b.Fatal("bad count", j, expect)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 17:59:32 -07:00
|
|
|
|
clear(buf)
|
2017-03-19 12:18:08 +01:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-06-04 14:41:31 -07:00
|
|
|
|
type SplitTest struct {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
s string
|
|
|
|
|
|
sep string
|
|
|
|
|
|
n int
|
|
|
|
|
|
a []string
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
2009-10-08 15:14:54 -07:00
|
|
|
|
|
|
|
|
|
|
var splittests = []SplitTest{
|
2019-04-02 22:38:39 +02:00
|
|
|
|
{"", "", -1, []string{}},
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{abcd, "a", 0, nil},
|
2019-04-02 22:38:39 +02:00
|
|
|
|
{abcd, "", 2, []string{"a", "bcd"}},
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{abcd, "a", -1, []string{"", "bcd"}},
|
|
|
|
|
|
{abcd, "z", -1, []string{"abcd"}},
|
|
|
|
|
|
{abcd, "", -1, []string{"a", "b", "c", "d"}},
|
|
|
|
|
|
{commas, ",", -1, []string{"1", "2", "3", "4"}},
|
|
|
|
|
|
{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
|
|
|
|
|
|
{faces, "☹", -1, []string{"☺☻", ""}},
|
|
|
|
|
|
{faces, "~", -1, []string{faces}},
|
|
|
|
|
|
{faces, "", -1, []string{"☺", "☻", "☹"}},
|
|
|
|
|
|
{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
|
|
|
|
|
|
{"1 2", " ", 3, []string{"1", "2"}},
|
|
|
|
|
|
{"123", "", 2, []string{"1", "23"}},
|
|
|
|
|
|
{"123", "", 17, []string{"1", "2", "3"}},
|
2022-04-05 20:28:16 +00:00
|
|
|
|
{"bT", "T", math.MaxInt / 4, []string{"b", ""}},
|
2022-06-22 20:57:50 -07:00
|
|
|
|
{"\xff-\xff", "", -1, []string{"\xff", "-", "\xff"}},
|
|
|
|
|
|
{"\xff-\xff", "-", -1, []string{"\xff", "\xff"}},
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
2009-09-13 21:35:18 -07:00
|
|
|
|
|
2009-06-04 14:41:31 -07:00
|
|
|
|
func TestSplit(t *testing.T) {
|
2009-06-24 19:02:29 -07:00
|
|
|
|
for _, tt := range splittests {
|
2011-06-28 09:43:14 +10:00
|
|
|
|
a := SplitN([]byte(tt.s), []byte(tt.sep), tt.n)
|
2017-10-30 16:05:18 -07:00
|
|
|
|
|
|
|
|
|
|
// Appending to the results should not change future results.
|
|
|
|
|
|
var x []byte
|
|
|
|
|
|
for _, v := range a {
|
|
|
|
|
|
x = append(v, 'z')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-01-07 10:48:06 +11:00
|
|
|
|
result := sliceOfString(a)
|
2024-07-24 10:32:22 +00:00
|
|
|
|
if !slices.Equal(result, tt.a) {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
|
|
|
|
|
|
continue
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
2024-08-09 07:33:36 +00:00
|
|
|
|
|
|
|
|
|
|
if tt.n < 0 {
|
|
|
|
|
|
b := sliceOfString(slices.Collect(SplitSeq([]byte(tt.s), []byte(tt.sep))))
|
|
|
|
|
|
if !slices.Equal(b, tt.a) {
|
|
|
|
|
|
t.Errorf(`collect(SplitSeq(%q, %q)) = %v; want %v`, tt.s, tt.sep, b, tt.a)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-04-02 22:38:39 +02:00
|
|
|
|
if tt.n == 0 || len(a) == 0 {
|
2010-07-01 14:08:14 -07:00
|
|
|
|
continue
|
|
|
|
|
|
}
|
2017-10-30 16:05:18 -07:00
|
|
|
|
|
|
|
|
|
|
if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
|
|
|
|
|
|
t.Errorf("last appended result was %s; want %s", x, want)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-02-25 16:01:29 -08:00
|
|
|
|
s := Join(a, []byte(tt.sep))
|
2009-06-04 14:41:31 -07:00
|
|
|
|
if string(s) != tt.s {
|
2009-11-09 12:07:39 -08:00
|
|
|
|
t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
2011-06-28 09:43:14 +10:00
|
|
|
|
if tt.n < 0 {
|
2024-08-05 03:00:42 +00:00
|
|
|
|
b := sliceOfString(Split([]byte(tt.s), []byte(tt.sep)))
|
|
|
|
|
|
if !slices.Equal(result, b) {
|
2011-06-28 09:43:14 +10:00
|
|
|
|
t.Errorf("Split disagrees withSplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2012-07-20 16:04:22 -03:00
|
|
|
|
if len(a) > 0 {
|
|
|
|
|
|
in, out := a[0], s
|
|
|
|
|
|
if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
|
|
|
|
|
|
t.Errorf("Join(%#v, %q) didn't copy", a, tt.sep)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2009-06-04 14:41:31 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2009-06-04 15:00:15 -07:00
|
|
|
|
|
2009-11-04 15:19:30 -08:00
|
|
|
|
var splitaftertests = []SplitTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{abcd, "a", -1, []string{"a", "bcd"}},
|
|
|
|
|
|
{abcd, "z", -1, []string{"abcd"}},
|
|
|
|
|
|
{abcd, "", -1, []string{"a", "b", "c", "d"}},
|
|
|
|
|
|
{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
|
|
|
|
|
|
{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
|
|
|
|
|
|
{faces, "☹", -1, []string{"☺☻☹", ""}},
|
|
|
|
|
|
{faces, "~", -1, []string{faces}},
|
|
|
|
|
|
{faces, "", -1, []string{"☺", "☻", "☹"}},
|
|
|
|
|
|
{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
|
|
|
|
|
|
{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
|
|
|
|
|
|
{"1 2", " ", 3, []string{"1 ", "2"}},
|
|
|
|
|
|
{"123", "", 2, []string{"1", "23"}},
|
|
|
|
|
|
{"123", "", 17, []string{"1", "2", "3"}},
|
2009-11-04 15:19:30 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestSplitAfter(t *testing.T) {
|
|
|
|
|
|
for _, tt := range splitaftertests {
|
2011-06-28 09:43:14 +10:00
|
|
|
|
a := SplitAfterN([]byte(tt.s), []byte(tt.sep), tt.n)
|
2017-10-30 16:05:18 -07:00
|
|
|
|
|
|
|
|
|
|
// Appending to the results should not change future results.
|
|
|
|
|
|
var x []byte
|
|
|
|
|
|
for _, v := range a {
|
|
|
|
|
|
x = append(v, 'z')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-01-07 10:48:06 +11:00
|
|
|
|
result := sliceOfString(a)
|
2024-07-24 10:32:22 +00:00
|
|
|
|
if !slices.Equal(result, tt.a) {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
|
|
|
|
|
|
continue
|
2009-11-04 15:19:30 -08:00
|
|
|
|
}
|
2017-10-30 16:05:18 -07:00
|
|
|
|
|
2024-08-09 07:33:36 +00:00
|
|
|
|
if tt.n < 0 {
|
|
|
|
|
|
b := sliceOfString(slices.Collect(SplitAfterSeq([]byte(tt.s), []byte(tt.sep))))
|
|
|
|
|
|
if !slices.Equal(b, tt.a) {
|
|
|
|
|
|
t.Errorf(`collect(SplitAfterSeq(%q, %q)) = %v; want %v`, tt.s, tt.sep, b, tt.a)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-30 16:05:18 -07:00
|
|
|
|
if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
|
|
|
|
|
|
t.Errorf("last appended result was %s; want %s", x, want)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-12-15 15:33:31 -08:00
|
|
|
|
s := Join(a, nil)
|
2009-11-04 15:19:30 -08:00
|
|
|
|
if string(s) != tt.s {
|
2009-11-09 12:07:39 -08:00
|
|
|
|
t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
|
2009-11-04 15:19:30 -08:00
|
|
|
|
}
|
2011-06-28 09:43:14 +10:00
|
|
|
|
if tt.n < 0 {
|
2024-08-05 03:00:42 +00:00
|
|
|
|
b := sliceOfString(SplitAfter([]byte(tt.s), []byte(tt.sep)))
|
|
|
|
|
|
if !slices.Equal(result, b) {
|
2011-06-28 09:43:14 +10:00
|
|
|
|
t.Errorf("SplitAfter disagrees withSplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2009-11-04 15:19:30 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-12-15 21:09:55 -08:00
|
|
|
|
type FieldsTest struct {
|
|
|
|
|
|
s string
|
|
|
|
|
|
a []string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var fieldstests = []FieldsTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", []string{}},
|
|
|
|
|
|
{" ", []string{}},
|
|
|
|
|
|
{" \t ", []string{}},
|
|
|
|
|
|
{" abc ", []string{"abc"}},
|
|
|
|
|
|
{"1 2 3 4", []string{"1", "2", "3", "4"}},
|
|
|
|
|
|
{"1 2 3 4", []string{"1", "2", "3", "4"}},
|
|
|
|
|
|
{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
|
|
|
|
|
|
{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
|
|
|
|
|
|
{"\u2000\u2001\u2002", []string{}},
|
|
|
|
|
|
{"\n™\t™\n", []string{"™", "™"}},
|
|
|
|
|
|
{faces, []string{faces}},
|
2009-12-15 21:09:55 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestFields(t *testing.T) {
|
|
|
|
|
|
for _, tt := range fieldstests {
|
2017-10-30 16:05:18 -07:00
|
|
|
|
b := []byte(tt.s)
|
|
|
|
|
|
a := Fields(b)
|
|
|
|
|
|
|
|
|
|
|
|
// Appending to the results should not change future results.
|
|
|
|
|
|
var x []byte
|
|
|
|
|
|
for _, v := range a {
|
|
|
|
|
|
x = append(v, 'z')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-01-07 10:48:06 +11:00
|
|
|
|
result := sliceOfString(a)
|
2024-07-24 10:32:22 +00:00
|
|
|
|
if !slices.Equal(result, tt.a) {
|
2009-12-15 21:09:55 -08:00
|
|
|
|
t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2017-10-30 16:05:18 -07:00
|
|
|
|
|
2024-08-09 07:33:36 +00:00
|
|
|
|
result2 := sliceOfString(collect(t, FieldsSeq([]byte(tt.s))))
|
|
|
|
|
|
if !slices.Equal(result2, tt.a) {
|
|
|
|
|
|
t.Errorf(`collect(FieldsSeq(%q)) = %v; want %v`, tt.s, result2, tt.a)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-30 16:05:18 -07:00
|
|
|
|
if string(b) != tt.s {
|
|
|
|
|
|
t.Errorf("slice changed to %s; want %s", string(b), tt.s)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(tt.a) > 0 {
|
|
|
|
|
|
if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
|
|
|
|
|
|
t.Errorf("last appended result was %s; want %s", x, want)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2009-12-15 21:09:55 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-08-05 23:11:06 +10:00
|
|
|
|
func TestFieldsFunc(t *testing.T) {
|
2012-09-18 15:02:08 -04:00
|
|
|
|
for _, tt := range fieldstests {
|
|
|
|
|
|
a := FieldsFunc([]byte(tt.s), unicode.IsSpace)
|
2013-01-07 10:48:06 +11:00
|
|
|
|
result := sliceOfString(a)
|
2024-07-24 10:32:22 +00:00
|
|
|
|
if !slices.Equal(result, tt.a) {
|
2012-09-18 15:02:08 -04:00
|
|
|
|
t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2011-10-25 22:22:09 -07:00
|
|
|
|
pred := func(c rune) bool { return c == 'X' }
|
2010-08-05 23:11:06 +10:00
|
|
|
|
var fieldsFuncTests = []FieldsTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", []string{}},
|
|
|
|
|
|
{"XX", []string{}},
|
|
|
|
|
|
{"XXhiXXX", []string{"hi"}},
|
|
|
|
|
|
{"aXXbXXXcX", []string{"a", "b", "c"}},
|
2010-08-05 23:11:06 +10:00
|
|
|
|
}
|
|
|
|
|
|
for _, tt := range fieldsFuncTests {
|
2017-10-30 16:05:18 -07:00
|
|
|
|
b := []byte(tt.s)
|
|
|
|
|
|
a := FieldsFunc(b, pred)
|
|
|
|
|
|
|
|
|
|
|
|
// Appending to the results should not change future results.
|
|
|
|
|
|
var x []byte
|
|
|
|
|
|
for _, v := range a {
|
|
|
|
|
|
x = append(v, 'z')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-01-07 10:48:06 +11:00
|
|
|
|
result := sliceOfString(a)
|
2024-07-24 10:32:22 +00:00
|
|
|
|
if !slices.Equal(result, tt.a) {
|
2010-08-05 23:11:06 +10:00
|
|
|
|
t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
|
|
|
|
|
|
}
|
2017-10-30 16:05:18 -07:00
|
|
|
|
|
2024-08-09 07:33:36 +00:00
|
|
|
|
result2 := sliceOfString(collect(t, FieldsFuncSeq([]byte(tt.s), pred)))
|
|
|
|
|
|
if !slices.Equal(result2, tt.a) {
|
|
|
|
|
|
t.Errorf(`collect(FieldsFuncSeq(%q)) = %v; want %v`, tt.s, result2, tt.a)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-30 16:05:18 -07:00
|
|
|
|
if string(b) != tt.s {
|
|
|
|
|
|
t.Errorf("slice changed to %s; want %s", b, tt.s)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(tt.a) > 0 {
|
|
|
|
|
|
if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
|
|
|
|
|
|
t.Errorf("last appended result was %s; want %s", x, want)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-08-05 23:11:06 +10:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-01-07 10:48:06 +11:00
|
|
|
|
// Test case for any function which accepts and returns a byte slice.
|
2019-03-27 07:36:27 -04:00
|
|
|
|
// For ease of creation, we write the input byte slice as a string.
|
2009-09-01 13:46:59 -07:00
|
|
|
|
type StringTest struct {
|
2019-03-27 07:36:27 -04:00
|
|
|
|
in string
|
|
|
|
|
|
out []byte
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-10-08 15:14:54 -07:00
|
|
|
|
var upperTests = []StringTest{
|
2019-03-27 07:36:27 -04:00
|
|
|
|
{"", []byte("")},
|
2019-04-08 15:53:35 +02:00
|
|
|
|
{"ONLYUPPER", []byte("ONLYUPPER")},
|
2019-03-27 07:36:27 -04:00
|
|
|
|
{"abc", []byte("ABC")},
|
|
|
|
|
|
{"AbC123", []byte("ABC123")},
|
|
|
|
|
|
{"azAZ09_", []byte("AZAZ09_")},
|
2019-04-08 15:53:35 +02:00
|
|
|
|
{"longStrinGwitHmixofsmaLLandcAps", []byte("LONGSTRINGWITHMIXOFSMALLANDCAPS")},
|
|
|
|
|
|
{"long\u0250string\u0250with\u0250nonascii\u2C6Fchars", []byte("LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS")},
|
2019-03-27 07:36:27 -04:00
|
|
|
|
{"\u0250\u0250\u0250\u0250\u0250", []byte("\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F")}, // grows one byte per char
|
2019-04-08 15:53:35 +02:00
|
|
|
|
{"a\u0080\U0010FFFF", []byte("A\u0080\U0010FFFF")}, // test utf8.RuneSelf and utf8.MaxRune
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-10-08 15:14:54 -07:00
|
|
|
|
var lowerTests = []StringTest{
|
2019-03-27 07:36:27 -04:00
|
|
|
|
{"", []byte("")},
|
|
|
|
|
|
{"abc", []byte("abc")},
|
|
|
|
|
|
{"AbC123", []byte("abc123")},
|
|
|
|
|
|
{"azAZ09_", []byte("azaz09_")},
|
2019-04-08 15:53:35 +02:00
|
|
|
|
{"longStrinGwitHmixofsmaLLandcAps", []byte("longstringwithmixofsmallandcaps")},
|
|
|
|
|
|
{"LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS", []byte("long\u0250string\u0250with\u0250nonascii\u0250chars")},
|
2019-03-27 07:36:27 -04:00
|
|
|
|
{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", []byte("\u0251\u0251\u0251\u0251\u0251")}, // shrinks one byte per char
|
2019-04-08 15:53:35 +02:00
|
|
|
|
{"A\u0080\U0010FFFF", []byte("a\u0080\U0010FFFF")}, // test utf8.RuneSelf and utf8.MaxRune
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
|
|
|
|
|
|
|
2009-10-08 15:14:54 -07:00
|
|
|
|
var trimSpaceTests = []StringTest{
|
2019-03-27 07:36:27 -04:00
|
|
|
|
{"", nil},
|
|
|
|
|
|
{" a", []byte("a")},
|
|
|
|
|
|
{"b ", []byte("b")},
|
|
|
|
|
|
{"abc", []byte("abc")},
|
|
|
|
|
|
{space + "abc" + space, []byte("abc")},
|
|
|
|
|
|
{" ", nil},
|
|
|
|
|
|
{"\u3000 ", nil},
|
|
|
|
|
|
{" \u3000", nil},
|
|
|
|
|
|
{" \t\r\n \t\t\r\r\n\n ", nil},
|
|
|
|
|
|
{" \t\r\n x\t\t\r\r\n\n ", []byte("x")},
|
|
|
|
|
|
{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", []byte("x\t\t\r\r\ny")},
|
|
|
|
|
|
{"1 \t\r\n2", []byte("1 \t\r\n2")},
|
|
|
|
|
|
{" x\x80", []byte("x\x80")},
|
|
|
|
|
|
{" x\xc0", []byte("x\xc0")},
|
|
|
|
|
|
{"x \xc0\xc0 ", []byte("x \xc0\xc0")},
|
|
|
|
|
|
{"x \xc0", []byte("x \xc0")},
|
|
|
|
|
|
{"x \xc0 ", []byte("x \xc0")},
|
|
|
|
|
|
{"x \xc0\xc0 ", []byte("x \xc0\xc0")},
|
|
|
|
|
|
{"x ☺\xc0\xc0 ", []byte("x ☺\xc0\xc0")},
|
|
|
|
|
|
{"x ☺ ", []byte("x ☺")},
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Execute f on each test case. funcName should be the name of f; it's used
|
|
|
|
|
|
// in failure reports.
|
|
|
|
|
|
func runStringTests(t *testing.T, f func([]byte) []byte, funcName string, testCases []StringTest) {
|
2009-09-15 09:41:59 -07:00
|
|
|
|
for _, tc := range testCases {
|
2019-03-27 07:36:27 -04:00
|
|
|
|
actual := f([]byte(tc.in))
|
|
|
|
|
|
if actual == nil && tc.out != nil {
|
|
|
|
|
|
t.Errorf("%s(%q) = nil; want %q", funcName, tc.in, tc.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
if actual != nil && tc.out == nil {
|
|
|
|
|
|
t.Errorf("%s(%q) = %q; want nil", funcName, tc.in, actual)
|
|
|
|
|
|
}
|
|
|
|
|
|
if !Equal(actual, tc.out) {
|
2009-11-09 12:07:39 -08:00
|
|
|
|
t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-10-25 22:22:09 -07:00
|
|
|
|
func tenRunes(r rune) string {
|
|
|
|
|
|
runes := make([]rune, 10)
|
|
|
|
|
|
for i := range runes {
|
|
|
|
|
|
runes[i] = r
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
2011-10-25 22:22:09 -07:00
|
|
|
|
return string(runes)
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-11-15 12:07:27 -08:00
|
|
|
|
// User-defined self-inverse mapping function
|
2011-10-25 22:22:09 -07:00
|
|
|
|
func rot13(r rune) rune {
|
|
|
|
|
|
const step = 13
|
|
|
|
|
|
if r >= 'a' && r <= 'z' {
|
|
|
|
|
|
return ((r - 'a' + step) % 26) + 'a'
|
2009-11-15 12:07:27 -08:00
|
|
|
|
}
|
2011-10-25 22:22:09 -07:00
|
|
|
|
if r >= 'A' && r <= 'Z' {
|
|
|
|
|
|
return ((r - 'A' + step) % 26) + 'A'
|
2009-11-15 12:07:27 -08:00
|
|
|
|
}
|
2011-10-25 22:22:09 -07:00
|
|
|
|
return r
|
2009-11-15 12:07:27 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-09-01 13:46:59 -07:00
|
|
|
|
func TestMap(t *testing.T) {
|
|
|
|
|
|
// Run a couple of awful growth/shrinkage tests
|
2009-12-15 15:33:31 -08:00
|
|
|
|
a := tenRunes('a')
|
2009-11-15 12:07:27 -08:00
|
|
|
|
|
2025-10-31 17:42:00 +08:00
|
|
|
|
// 1. Grow. This triggers two reallocations in Map.
|
2011-10-25 22:22:09 -07:00
|
|
|
|
maxRune := func(r rune) rune { return unicode.MaxRune }
|
2010-10-26 21:52:54 -07:00
|
|
|
|
m := Map(maxRune, []byte(a))
|
2009-12-15 15:33:31 -08:00
|
|
|
|
expect := tenRunes(unicode.MaxRune)
|
2009-09-01 13:46:59 -07:00
|
|
|
|
if string(m) != expect {
|
2009-11-09 12:07:39 -08:00
|
|
|
|
t.Errorf("growing: expected %q got %q", expect, m)
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
2009-11-15 12:07:27 -08:00
|
|
|
|
|
2009-09-01 13:46:59 -07:00
|
|
|
|
// 2. Shrink
|
2011-10-25 22:22:09 -07:00
|
|
|
|
minRune := func(r rune) rune { return 'a' }
|
2010-10-26 21:52:54 -07:00
|
|
|
|
m = Map(minRune, []byte(tenRunes(unicode.MaxRune)))
|
2009-12-15 15:33:31 -08:00
|
|
|
|
expect = a
|
2009-09-01 13:46:59 -07:00
|
|
|
|
if string(m) != expect {
|
2009-11-09 12:07:39 -08:00
|
|
|
|
t.Errorf("shrinking: expected %q got %q", expect, m)
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
2009-11-15 12:07:27 -08:00
|
|
|
|
|
|
|
|
|
|
// 3. Rot13
|
2010-10-26 21:52:54 -07:00
|
|
|
|
m = Map(rot13, []byte("a to zed"))
|
2009-12-15 15:33:31 -08:00
|
|
|
|
expect = "n gb mrq"
|
2009-11-15 12:07:27 -08:00
|
|
|
|
if string(m) != expect {
|
|
|
|
|
|
t.Errorf("rot13: expected %q got %q", expect, m)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Rot13^2
|
2010-10-26 21:52:54 -07:00
|
|
|
|
m = Map(rot13, Map(rot13, []byte("a to zed")))
|
2009-12-15 15:33:31 -08:00
|
|
|
|
expect = "a to zed"
|
2009-11-15 12:07:27 -08:00
|
|
|
|
if string(m) != expect {
|
|
|
|
|
|
t.Errorf("rot13: expected %q got %q", expect, m)
|
|
|
|
|
|
}
|
2009-12-11 10:37:48 -08:00
|
|
|
|
|
|
|
|
|
|
// 5. Drop
|
2011-10-25 22:22:09 -07:00
|
|
|
|
dropNotLatin := func(r rune) rune {
|
|
|
|
|
|
if unicode.Is(unicode.Latin, r) {
|
|
|
|
|
|
return r
|
2009-12-11 10:37:48 -08:00
|
|
|
|
}
|
2009-12-15 15:33:31 -08:00
|
|
|
|
return -1
|
|
|
|
|
|
}
|
2010-10-26 21:52:54 -07:00
|
|
|
|
m = Map(dropNotLatin, []byte("Hello, 세계"))
|
2009-12-15 15:33:31 -08:00
|
|
|
|
expect = "Hello"
|
2009-12-11 10:37:48 -08:00
|
|
|
|
if string(m) != expect {
|
|
|
|
|
|
t.Errorf("drop: expected %q got %q", expect, m)
|
|
|
|
|
|
}
|
2014-03-18 20:52:58 -07:00
|
|
|
|
|
|
|
|
|
|
// 6. Invalid rune
|
|
|
|
|
|
invalidRune := func(r rune) rune {
|
|
|
|
|
|
return utf8.MaxRune + 1
|
|
|
|
|
|
}
|
|
|
|
|
|
m = Map(invalidRune, []byte("x"))
|
|
|
|
|
|
expect = "\uFFFD"
|
|
|
|
|
|
if string(m) != expect {
|
|
|
|
|
|
t.Errorf("invalidRune: expected %q got %q", expect, m)
|
|
|
|
|
|
}
|
2009-09-01 13:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-12-15 15:33:31 -08:00
|
|
|
|
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
2009-09-01 13:46:59 -07:00
|
|
|
|
|
2009-12-15 15:33:31 -08:00
|
|
|
|
func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
|
2009-09-01 13:46:59 -07:00
|
|
|
|
|
2019-04-08 15:53:35 +02:00
|
|
|
|
func BenchmarkToUpper(b *testing.B) {
|
|
|
|
|
|
for _, tc := range upperTests {
|
|
|
|
|
|
tin := []byte(tc.in)
|
|
|
|
|
|
b.Run(tc.in, func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
actual := ToUpper(tin)
|
|
|
|
|
|
if !Equal(actual, tc.out) {
|
|
|
|
|
|
b.Errorf("ToUpper(%q) = %q; want %q", tc.in, actual, tc.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkToLower(b *testing.B) {
|
|
|
|
|
|
for _, tc := range lowerTests {
|
|
|
|
|
|
tin := []byte(tc.in)
|
|
|
|
|
|
b.Run(tc.in, func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
actual := ToLower(tin)
|
|
|
|
|
|
if !Equal(actual, tc.out) {
|
|
|
|
|
|
b.Errorf("ToLower(%q) = %q; want %q", tc.in, actual, tc.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-13 22:40:23 +02:00
|
|
|
|
var toValidUTF8Tests = []struct {
|
|
|
|
|
|
in string
|
|
|
|
|
|
repl string
|
|
|
|
|
|
out string
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"", "\uFFFD", ""},
|
|
|
|
|
|
{"abc", "\uFFFD", "abc"},
|
|
|
|
|
|
{"\uFDDD", "\uFFFD", "\uFDDD"},
|
|
|
|
|
|
{"a\xffb", "\uFFFD", "a\uFFFDb"},
|
|
|
|
|
|
{"a\xffb\uFFFD", "X", "aXb\uFFFD"},
|
|
|
|
|
|
{"a☺\xffb☺\xC0\xAFc☺\xff", "", "a☺b☺c☺"},
|
|
|
|
|
|
{"a☺\xffb☺\xC0\xAFc☺\xff", "日本語", "a☺日本語b☺日本語c☺日本語"},
|
|
|
|
|
|
{"\xC0\xAF", "\uFFFD", "\uFFFD"},
|
|
|
|
|
|
{"\xE0\x80\xAF", "\uFFFD", "\uFFFD"},
|
|
|
|
|
|
{"\xed\xa0\x80", "abc", "abc"},
|
|
|
|
|
|
{"\xed\xbf\xbf", "\uFFFD", "\uFFFD"},
|
|
|
|
|
|
{"\xF0\x80\x80\xaf", "☺", "☺"},
|
|
|
|
|
|
{"\xF8\x80\x80\x80\xAF", "\uFFFD", "\uFFFD"},
|
|
|
|
|
|
{"\xFC\x80\x80\x80\x80\xAF", "\uFFFD", "\uFFFD"},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestToValidUTF8(t *testing.T) {
|
|
|
|
|
|
for _, tc := range toValidUTF8Tests {
|
|
|
|
|
|
got := ToValidUTF8([]byte(tc.in), []byte(tc.repl))
|
|
|
|
|
|
if !Equal(got, []byte(tc.out)) {
|
|
|
|
|
|
t.Errorf("ToValidUTF8(%q, %q) = %q; want %q", tc.in, tc.repl, got, tc.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-12-15 15:33:31 -08:00
|
|
|
|
func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
|
2009-09-13 21:35:18 -07:00
|
|
|
|
|
2009-11-16 12:40:01 -08:00
|
|
|
|
type RepeatTest struct {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
in, out string
|
|
|
|
|
|
count int
|
2009-11-16 12:40:01 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-22 14:18:33 +09:00
|
|
|
|
var longString = "a" + string(make([]byte, 1<<16)) + "z"
|
|
|
|
|
|
|
2009-11-16 12:40:01 -08:00
|
|
|
|
var RepeatTests = []RepeatTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", "", 0},
|
|
|
|
|
|
{"", "", 1},
|
|
|
|
|
|
{"", "", 2},
|
|
|
|
|
|
{"-", "", 0},
|
|
|
|
|
|
{"-", "-", 1},
|
|
|
|
|
|
{"-", "----------", 10},
|
|
|
|
|
|
{"abc ", "abc abc abc ", 3},
|
2022-07-22 14:18:33 +09:00
|
|
|
|
// Tests for results over the chunkLimit
|
|
|
|
|
|
{string(rune(0)), string(make([]byte, 1<<16)), 1 << 16},
|
|
|
|
|
|
{longString, longString + longString, 2},
|
2009-11-16 12:40:01 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestRepeat(t *testing.T) {
|
|
|
|
|
|
for _, tt := range RepeatTests {
|
2010-02-25 16:01:29 -08:00
|
|
|
|
tin := []byte(tt.in)
|
|
|
|
|
|
tout := []byte(tt.out)
|
2009-12-15 15:33:31 -08:00
|
|
|
|
a := Repeat(tin, tt.count)
|
2009-11-16 12:40:01 -08:00
|
|
|
|
if !Equal(a, tout) {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
t.Errorf("Repeat(%q, %d) = %q; want %q", tin, tt.count, a, tout)
|
|
|
|
|
|
continue
|
2009-11-16 12:40:01 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2009-12-02 20:47:38 -08:00
|
|
|
|
|
2016-09-28 01:54:38 -07:00
|
|
|
|
func repeat(b []byte, count int) (err error) {
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
|
|
switch v := r.(type) {
|
|
|
|
|
|
case error:
|
|
|
|
|
|
err = v
|
|
|
|
|
|
default:
|
|
|
|
|
|
err = fmt.Errorf("%s", v)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
Repeat(b, count)
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// See Issue golang.org/issue/16237
|
|
|
|
|
|
func TestRepeatCatchesOverflow(t *testing.T) {
|
2024-05-03 09:56:47 +00:00
|
|
|
|
type testCase struct {
|
2016-09-28 01:54:38 -07:00
|
|
|
|
s string
|
|
|
|
|
|
count int
|
|
|
|
|
|
errStr string
|
2024-05-03 09:56:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
runTestCases := func(prefix string, tests []testCase) {
|
|
|
|
|
|
for i, tt := range tests {
|
|
|
|
|
|
err := repeat([]byte(tt.s), tt.count)
|
|
|
|
|
|
if tt.errStr == "" {
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
t.Errorf("#%d panicked %v", i, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if err == nil || !strings.Contains(err.Error(), tt.errStr) {
|
|
|
|
|
|
t.Errorf("%s#%d got %q want %q", prefix, i, err, tt.errStr)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const maxInt = int(^uint(0) >> 1)
|
|
|
|
|
|
|
|
|
|
|
|
runTestCases("", []testCase{
|
2016-09-28 01:54:38 -07:00
|
|
|
|
0: {"--", -2147483647, "negative"},
|
2024-05-03 09:56:47 +00:00
|
|
|
|
1: {"", maxInt, ""},
|
2016-09-28 01:54:38 -07:00
|
|
|
|
2: {"-", 10, ""},
|
|
|
|
|
|
3: {"gopher", 0, ""},
|
|
|
|
|
|
4: {"-", -1, "negative"},
|
|
|
|
|
|
5: {"--", -102, "negative"},
|
|
|
|
|
|
6: {string(make([]byte, 255)), int((^uint(0))/255 + 1), "overflow"},
|
2024-05-03 09:56:47 +00:00
|
|
|
|
})
|
2016-09-28 01:54:38 -07:00
|
|
|
|
|
2024-05-03 09:56:47 +00:00
|
|
|
|
const is64Bit = 1<<(^uintptr(0)>>63)/2 != 0
|
|
|
|
|
|
if !is64Bit {
|
|
|
|
|
|
return
|
2016-09-28 01:54:38 -07:00
|
|
|
|
}
|
2024-05-03 09:56:47 +00:00
|
|
|
|
|
|
|
|
|
|
runTestCases("64-bit", []testCase{
|
|
|
|
|
|
0: {"-", maxInt, "out of range"},
|
|
|
|
|
|
})
|
2016-09-28 01:54:38 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-12-02 20:47:38 -08:00
|
|
|
|
type RunesTest struct {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
in string
|
2011-10-25 22:22:09 -07:00
|
|
|
|
out []rune
|
2009-12-15 15:33:31 -08:00
|
|
|
|
lossy bool
|
2009-12-02 20:47:38 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var RunesTests = []RunesTest{
|
2011-10-25 22:22:09 -07:00
|
|
|
|
{"", []rune{}, false},
|
|
|
|
|
|
{" ", []rune{32}, false},
|
|
|
|
|
|
{"ABC", []rune{65, 66, 67}, false},
|
|
|
|
|
|
{"abc", []rune{97, 98, 99}, false},
|
|
|
|
|
|
{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
|
|
|
|
|
|
{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
|
|
|
|
|
|
{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
|
2009-12-02 20:47:38 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestRunes(t *testing.T) {
|
|
|
|
|
|
for _, tt := range RunesTests {
|
2010-02-25 16:01:29 -08:00
|
|
|
|
tin := []byte(tt.in)
|
2009-12-15 15:33:31 -08:00
|
|
|
|
a := Runes(tin)
|
2024-07-24 10:32:22 +00:00
|
|
|
|
if !slices.Equal(a, tt.out) {
|
2009-12-15 15:33:31 -08:00
|
|
|
|
t.Errorf("Runes(%q) = %v; want %v", tin, a, tt.out)
|
|
|
|
|
|
continue
|
2009-12-02 20:47:38 -08:00
|
|
|
|
}
|
|
|
|
|
|
if !tt.lossy {
|
|
|
|
|
|
// can only test reassembly if we didn't lose information
|
2009-12-15 15:33:31 -08:00
|
|
|
|
s := string(a)
|
2009-12-02 20:47:38 -08:00
|
|
|
|
if s != tt.in {
|
|
|
|
|
|
t.Errorf("string(Runes(%q)) = %x; want %x", tin, s, tin)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-05-18 23:01:05 -07:00
|
|
|
|
|
|
|
|
|
|
type TrimTest struct {
|
2013-02-01 08:41:25 -08:00
|
|
|
|
f string
|
|
|
|
|
|
in, arg, out string
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var trimTests = []TrimTest{
|
2011-11-13 22:57:19 -05:00
|
|
|
|
{"Trim", "abba", "a", "bb"},
|
|
|
|
|
|
{"Trim", "abba", "ab", ""},
|
|
|
|
|
|
{"TrimLeft", "abba", "ab", ""},
|
|
|
|
|
|
{"TrimRight", "abba", "ab", ""},
|
|
|
|
|
|
{"TrimLeft", "abba", "a", "bba"},
|
2021-05-29 19:11:37 -07:00
|
|
|
|
{"TrimLeft", "abba", "b", "abba"},
|
2011-11-13 22:57:19 -05:00
|
|
|
|
{"TrimRight", "abba", "a", "abb"},
|
2021-05-29 19:11:37 -07:00
|
|
|
|
{"TrimRight", "abba", "b", "abba"},
|
2011-11-13 22:57:19 -05:00
|
|
|
|
{"Trim", "<tag>", "<>", "tag"},
|
|
|
|
|
|
{"Trim", "* listitem", " *", "listitem"},
|
|
|
|
|
|
{"Trim", `"quote"`, `"`, "quote"},
|
|
|
|
|
|
{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
{"Trim", "\x80test\xff", "\xff", "test"},
|
|
|
|
|
|
{"Trim", " Ġ ", " ", "Ġ"},
|
|
|
|
|
|
{"Trim", " Ġİ0", "0 ", "Ġİ"},
|
2010-05-18 23:01:05 -07:00
|
|
|
|
//empty string tests
|
2011-11-13 22:57:19 -05:00
|
|
|
|
{"Trim", "abba", "", "abba"},
|
|
|
|
|
|
{"Trim", "", "123", ""},
|
|
|
|
|
|
{"Trim", "", "", ""},
|
|
|
|
|
|
{"TrimLeft", "abba", "", "abba"},
|
|
|
|
|
|
{"TrimLeft", "", "123", ""},
|
|
|
|
|
|
{"TrimLeft", "", "", ""},
|
|
|
|
|
|
{"TrimRight", "abba", "", "abba"},
|
|
|
|
|
|
{"TrimRight", "", "123", ""},
|
|
|
|
|
|
{"TrimRight", "", "", ""},
|
|
|
|
|
|
{"TrimRight", "☺\xc0", "☺", "☺\xc0"},
|
2013-02-01 08:41:25 -08:00
|
|
|
|
{"TrimPrefix", "aabb", "a", "abb"},
|
|
|
|
|
|
{"TrimPrefix", "aabb", "b", "aabb"},
|
|
|
|
|
|
{"TrimSuffix", "aabb", "a", "aabb"},
|
|
|
|
|
|
{"TrimSuffix", "aabb", "b", "aab"},
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-18 12:14:20 -07:00
|
|
|
|
type TrimNilTest struct {
|
|
|
|
|
|
f string
|
|
|
|
|
|
in []byte
|
|
|
|
|
|
arg string
|
|
|
|
|
|
out []byte
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var trimNilTests = []TrimNilTest{
|
|
|
|
|
|
{"Trim", nil, "", nil},
|
|
|
|
|
|
{"Trim", []byte{}, "", nil},
|
|
|
|
|
|
{"Trim", []byte{'a'}, "a", nil},
|
|
|
|
|
|
{"Trim", []byte{'a', 'a'}, "a", nil},
|
|
|
|
|
|
{"Trim", []byte{'a'}, "ab", nil},
|
|
|
|
|
|
{"Trim", []byte{'a', 'b'}, "ab", nil},
|
|
|
|
|
|
{"Trim", []byte("☺"), "☺", nil},
|
|
|
|
|
|
{"TrimLeft", nil, "", nil},
|
|
|
|
|
|
{"TrimLeft", []byte{}, "", nil},
|
|
|
|
|
|
{"TrimLeft", []byte{'a'}, "a", nil},
|
|
|
|
|
|
{"TrimLeft", []byte{'a', 'a'}, "a", nil},
|
|
|
|
|
|
{"TrimLeft", []byte{'a'}, "ab", nil},
|
|
|
|
|
|
{"TrimLeft", []byte{'a', 'b'}, "ab", nil},
|
|
|
|
|
|
{"TrimLeft", []byte("☺"), "☺", nil},
|
|
|
|
|
|
{"TrimRight", nil, "", nil},
|
|
|
|
|
|
{"TrimRight", []byte{}, "", []byte{}},
|
|
|
|
|
|
{"TrimRight", []byte{'a'}, "a", []byte{}},
|
|
|
|
|
|
{"TrimRight", []byte{'a', 'a'}, "a", []byte{}},
|
|
|
|
|
|
{"TrimRight", []byte{'a'}, "ab", []byte{}},
|
|
|
|
|
|
{"TrimRight", []byte{'a', 'b'}, "ab", []byte{}},
|
|
|
|
|
|
{"TrimRight", []byte("☺"), "☺", []byte{}},
|
|
|
|
|
|
{"TrimPrefix", nil, "", nil},
|
|
|
|
|
|
{"TrimPrefix", []byte{}, "", []byte{}},
|
|
|
|
|
|
{"TrimPrefix", []byte{'a'}, "a", []byte{}},
|
|
|
|
|
|
{"TrimPrefix", []byte("☺"), "☺", []byte{}},
|
|
|
|
|
|
{"TrimSuffix", nil, "", nil},
|
|
|
|
|
|
{"TrimSuffix", []byte{}, "", []byte{}},
|
|
|
|
|
|
{"TrimSuffix", []byte{'a'}, "a", []byte{}},
|
|
|
|
|
|
{"TrimSuffix", []byte("☺"), "☺", []byte{}},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-05-18 23:01:05 -07:00
|
|
|
|
func TestTrim(t *testing.T) {
|
2022-03-18 12:14:20 -07:00
|
|
|
|
toFn := func(name string) (func([]byte, string) []byte, func([]byte, []byte) []byte) {
|
2011-11-13 22:57:19 -05:00
|
|
|
|
switch name {
|
|
|
|
|
|
case "Trim":
|
2022-03-18 12:14:20 -07:00
|
|
|
|
return Trim, nil
|
2011-11-13 22:57:19 -05:00
|
|
|
|
case "TrimLeft":
|
2022-03-18 12:14:20 -07:00
|
|
|
|
return TrimLeft, nil
|
2011-11-13 22:57:19 -05:00
|
|
|
|
case "TrimRight":
|
2022-03-18 12:14:20 -07:00
|
|
|
|
return TrimRight, nil
|
2013-02-01 08:41:25 -08:00
|
|
|
|
case "TrimPrefix":
|
2022-03-18 12:14:20 -07:00
|
|
|
|
return nil, TrimPrefix
|
2013-02-01 08:41:25 -08:00
|
|
|
|
case "TrimSuffix":
|
2022-03-18 12:14:20 -07:00
|
|
|
|
return nil, TrimSuffix
|
2010-05-18 23:01:05 -07:00
|
|
|
|
default:
|
2011-11-28 09:50:51 -08:00
|
|
|
|
t.Errorf("Undefined trim function %s", name)
|
2022-03-18 12:14:20 -07:00
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, tc := range trimTests {
|
|
|
|
|
|
name := tc.f
|
|
|
|
|
|
f, fb := toFn(name)
|
|
|
|
|
|
if f == nil && fb == nil {
|
|
|
|
|
|
continue
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
2013-02-01 08:41:25 -08:00
|
|
|
|
var actual string
|
|
|
|
|
|
if f != nil {
|
|
|
|
|
|
actual = string(f([]byte(tc.in), tc.arg))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
actual = string(fb([]byte(tc.in), []byte(tc.arg)))
|
|
|
|
|
|
}
|
2010-05-18 23:01:05 -07:00
|
|
|
|
if actual != tc.out {
|
2013-02-01 08:41:25 -08:00
|
|
|
|
t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-03-18 12:14:20 -07:00
|
|
|
|
|
|
|
|
|
|
for _, tc := range trimNilTests {
|
|
|
|
|
|
name := tc.f
|
|
|
|
|
|
f, fb := toFn(name)
|
|
|
|
|
|
if f == nil && fb == nil {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
var actual []byte
|
|
|
|
|
|
if f != nil {
|
|
|
|
|
|
actual = f(tc.in, tc.arg)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
actual = fb(tc.in, []byte(tc.arg))
|
|
|
|
|
|
}
|
|
|
|
|
|
report := func(s []byte) string {
|
|
|
|
|
|
if s == nil {
|
|
|
|
|
|
return "nil"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return fmt.Sprintf("%q", s)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(actual) != 0 {
|
|
|
|
|
|
t.Errorf("%s(%s, %q) returned non-empty value", name, report(tc.in), tc.arg)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
actualNil := actual == nil
|
|
|
|
|
|
outNil := tc.out == nil
|
|
|
|
|
|
if actualNil != outNil {
|
|
|
|
|
|
t.Errorf("%s(%s, %q) got nil %t; want nil %t", name, report(tc.in), tc.arg, actualNil, outNil)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-07-23 12:34:35 -07:00
|
|
|
|
type predicate struct {
|
2011-10-25 22:22:09 -07:00
|
|
|
|
f func(r rune) bool
|
2010-07-23 12:34:35 -07:00
|
|
|
|
name string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var isSpace = predicate{unicode.IsSpace, "IsSpace"}
|
|
|
|
|
|
var isDigit = predicate{unicode.IsDigit, "IsDigit"}
|
|
|
|
|
|
var isUpper = predicate{unicode.IsUpper, "IsUpper"}
|
|
|
|
|
|
var isValidRune = predicate{
|
2011-10-25 22:22:09 -07:00
|
|
|
|
func(r rune) bool {
|
2010-07-23 12:34:35 -07:00
|
|
|
|
return r != utf8.RuneError
|
|
|
|
|
|
},
|
|
|
|
|
|
"IsValidRune",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-05-18 23:01:05 -07:00
|
|
|
|
type TrimFuncTest struct {
|
2019-03-28 17:49:43 -04:00
|
|
|
|
f predicate
|
|
|
|
|
|
in string
|
|
|
|
|
|
trimOut []byte
|
|
|
|
|
|
leftOut []byte
|
|
|
|
|
|
rightOut []byte
|
2010-07-23 12:34:35 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func not(p predicate) predicate {
|
|
|
|
|
|
return predicate{
|
2011-10-25 22:22:09 -07:00
|
|
|
|
func(r rune) bool {
|
2010-07-23 12:34:35 -07:00
|
|
|
|
return !p.f(r)
|
|
|
|
|
|
},
|
|
|
|
|
|
"not " + p.name,
|
|
|
|
|
|
}
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var trimFuncTests = []TrimFuncTest{
|
2019-03-28 17:49:43 -04:00
|
|
|
|
{isSpace, space + " hello " + space,
|
|
|
|
|
|
[]byte("hello"),
|
|
|
|
|
|
[]byte("hello " + space),
|
|
|
|
|
|
[]byte(space + " hello")},
|
|
|
|
|
|
{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51",
|
|
|
|
|
|
[]byte("hello"),
|
|
|
|
|
|
[]byte("hello34\u0e50\u0e51"),
|
|
|
|
|
|
[]byte("\u0e50\u0e5212hello")},
|
|
|
|
|
|
{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F",
|
|
|
|
|
|
[]byte("hello"),
|
|
|
|
|
|
[]byte("helloEF\u2C6F\u2C6FGH\u2C6F\u2C6F"),
|
|
|
|
|
|
[]byte("\u2C6F\u2C6F\u2C6F\u2C6FABCDhello")},
|
|
|
|
|
|
{not(isSpace), "hello" + space + "hello",
|
|
|
|
|
|
[]byte(space),
|
|
|
|
|
|
[]byte(space + "hello"),
|
|
|
|
|
|
[]byte("hello" + space)},
|
|
|
|
|
|
{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo",
|
|
|
|
|
|
[]byte("\u0e50\u0e521234\u0e50\u0e51"),
|
|
|
|
|
|
[]byte("\u0e50\u0e521234\u0e50\u0e51helo"),
|
|
|
|
|
|
[]byte("hello\u0e50\u0e521234\u0e50\u0e51")},
|
|
|
|
|
|
{isValidRune, "ab\xc0a\xc0cd",
|
|
|
|
|
|
[]byte("\xc0a\xc0"),
|
|
|
|
|
|
[]byte("\xc0a\xc0cd"),
|
|
|
|
|
|
[]byte("ab\xc0a\xc0")},
|
|
|
|
|
|
{not(isValidRune), "\xc0a\xc0",
|
|
|
|
|
|
[]byte("a"),
|
|
|
|
|
|
[]byte("a\xc0"),
|
|
|
|
|
|
[]byte("\xc0a")},
|
|
|
|
|
|
// The nils returned by TrimLeftFunc are odd behavior, but we need
|
|
|
|
|
|
// to preserve backwards compatibility.
|
|
|
|
|
|
{isSpace, "",
|
|
|
|
|
|
nil,
|
|
|
|
|
|
nil,
|
|
|
|
|
|
[]byte("")},
|
|
|
|
|
|
{isSpace, " ",
|
|
|
|
|
|
nil,
|
|
|
|
|
|
nil,
|
|
|
|
|
|
[]byte("")},
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestTrimFunc(t *testing.T) {
|
|
|
|
|
|
for _, tc := range trimFuncTests {
|
2019-03-28 17:49:43 -04:00
|
|
|
|
trimmers := []struct {
|
|
|
|
|
|
name string
|
|
|
|
|
|
trim func(s []byte, f func(r rune) bool) []byte
|
|
|
|
|
|
out []byte
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"TrimFunc", TrimFunc, tc.trimOut},
|
|
|
|
|
|
{"TrimLeftFunc", TrimLeftFunc, tc.leftOut},
|
|
|
|
|
|
{"TrimRightFunc", TrimRightFunc, tc.rightOut},
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, trimmer := range trimmers {
|
|
|
|
|
|
actual := trimmer.trim([]byte(tc.in), tc.f.f)
|
|
|
|
|
|
if actual == nil && trimmer.out != nil {
|
|
|
|
|
|
t.Errorf("%s(%q, %q) = nil; want %q", trimmer.name, tc.in, tc.f.name, trimmer.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
if actual != nil && trimmer.out == nil {
|
|
|
|
|
|
t.Errorf("%s(%q, %q) = %q; want nil", trimmer.name, tc.in, tc.f.name, actual)
|
|
|
|
|
|
}
|
|
|
|
|
|
if !Equal(actual, trimmer.out) {
|
|
|
|
|
|
t.Errorf("%s(%q, %q) = %q; want %q", trimmer.name, tc.in, tc.f.name, actual, trimmer.out)
|
|
|
|
|
|
}
|
2010-07-23 12:34:35 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type IndexFuncTest struct {
|
|
|
|
|
|
in string
|
|
|
|
|
|
f predicate
|
|
|
|
|
|
first, last int
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var indexFuncTests = []IndexFuncTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", isValidRune, -1, -1},
|
|
|
|
|
|
{"abc", isDigit, -1, -1},
|
|
|
|
|
|
{"0123", isDigit, 0, 3},
|
|
|
|
|
|
{"a1b", isDigit, 1, 1},
|
|
|
|
|
|
{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
|
|
|
|
|
|
{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
|
|
|
|
|
|
{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
|
|
|
|
|
|
{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
|
2010-07-23 12:34:35 -07:00
|
|
|
|
|
|
|
|
|
|
// tests of invalid UTF-8
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"\x801", isDigit, 1, 1},
|
|
|
|
|
|
{"\x80abc", isDigit, -1, -1},
|
|
|
|
|
|
{"\xc0a\xc0", isValidRune, 1, 1},
|
|
|
|
|
|
{"\xc0a\xc0", not(isValidRune), 0, 2},
|
|
|
|
|
|
{"\xc0☺\xc0", not(isValidRune), 0, 4},
|
|
|
|
|
|
{"\xc0☺\xc0\xc0", not(isValidRune), 0, 5},
|
|
|
|
|
|
{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
|
|
|
|
|
|
{"a\xe0\x80cd", not(isValidRune), 1, 2},
|
2010-07-23 12:34:35 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestIndexFunc(t *testing.T) {
|
|
|
|
|
|
for _, tc := range indexFuncTests {
|
|
|
|
|
|
first := IndexFunc([]byte(tc.in), tc.f.f)
|
|
|
|
|
|
if first != tc.first {
|
|
|
|
|
|
t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
|
|
|
|
|
|
}
|
|
|
|
|
|
last := LastIndexFunc([]byte(tc.in), tc.f.f)
|
|
|
|
|
|
if last != tc.last {
|
|
|
|
|
|
t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
|
2010-05-18 23:01:05 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-06-30 18:03:09 -07:00
|
|
|
|
|
|
|
|
|
|
type ReplaceTest struct {
|
|
|
|
|
|
in string
|
|
|
|
|
|
old, new string
|
|
|
|
|
|
n int
|
|
|
|
|
|
out string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var ReplaceTests = []ReplaceTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"hello", "l", "L", 0, "hello"},
|
|
|
|
|
|
{"hello", "l", "L", -1, "heLLo"},
|
|
|
|
|
|
{"hello", "x", "X", -1, "hello"},
|
|
|
|
|
|
{"", "x", "X", -1, ""},
|
|
|
|
|
|
{"radar", "r", "<r>", -1, "<r>ada<r>"},
|
|
|
|
|
|
{"", "", "<>", -1, "<>"},
|
|
|
|
|
|
{"banana", "a", "<>", -1, "b<>n<>n<>"},
|
|
|
|
|
|
{"banana", "a", "<>", 1, "b<>nana"},
|
|
|
|
|
|
{"banana", "a", "<>", 1000, "b<>n<>n<>"},
|
|
|
|
|
|
{"banana", "an", "<>", -1, "b<><>a"},
|
|
|
|
|
|
{"banana", "ana", "<>", -1, "b<>na"},
|
|
|
|
|
|
{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
|
|
|
|
|
|
{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
|
|
|
|
|
|
{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
|
|
|
|
|
|
{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
|
|
|
|
|
|
{"banana", "", "<>", 1, "<>banana"},
|
|
|
|
|
|
{"banana", "a", "a", -1, "banana"},
|
|
|
|
|
|
{"banana", "a", "a", 1, "banana"},
|
|
|
|
|
|
{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
|
2010-06-30 18:03:09 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestReplace(t *testing.T) {
|
|
|
|
|
|
for _, tt := range ReplaceTests {
|
2025-03-20 20:42:05 +00:00
|
|
|
|
var (
|
|
|
|
|
|
in = []byte(tt.in)
|
|
|
|
|
|
old = []byte(tt.old)
|
|
|
|
|
|
new = []byte(tt.new)
|
|
|
|
|
|
)
|
|
|
|
|
|
if !asan.Enabled {
|
|
|
|
|
|
allocs := testing.AllocsPerRun(10, func() { Replace(in, old, new, tt.n) })
|
|
|
|
|
|
if allocs > 1 {
|
|
|
|
|
|
t.Errorf("Replace(%q, %q, %q, %d) allocates %.2f objects", tt.in, tt.old, tt.new, tt.n, allocs)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
in = append(in, "<spare>"...)
|
2011-09-21 12:36:17 -03:00
|
|
|
|
in = in[:len(tt.in)]
|
2025-03-20 20:42:05 +00:00
|
|
|
|
out := Replace(in, old, new, tt.n)
|
2011-09-21 12:36:17 -03:00
|
|
|
|
if s := string(out); s != tt.out {
|
2010-06-30 18:03:09 -07:00
|
|
|
|
t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
|
|
|
|
|
|
}
|
2011-09-21 12:36:17 -03:00
|
|
|
|
if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
|
|
|
|
|
|
t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
|
|
|
|
|
|
}
|
2018-09-26 20:19:11 +00:00
|
|
|
|
if tt.n == -1 {
|
2025-03-20 20:42:05 +00:00
|
|
|
|
out := ReplaceAll(in, old, new)
|
2018-09-26 20:19:11 +00:00
|
|
|
|
if s := string(out); s != tt.out {
|
|
|
|
|
|
t.Errorf("ReplaceAll(%q, %q, %q) = %q, want %q", tt.in, tt.old, tt.new, s, tt.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-06-30 18:03:09 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-07-20 19:53:59 -07:00
|
|
|
|
|
2025-03-20 20:42:05 +00:00
|
|
|
|
func FuzzReplace(f *testing.F) {
|
|
|
|
|
|
for _, tt := range ReplaceTests {
|
|
|
|
|
|
f.Add([]byte(tt.in), []byte(tt.old), []byte(tt.new), tt.n)
|
|
|
|
|
|
}
|
|
|
|
|
|
f.Fuzz(func(t *testing.T, in, old, new []byte, n int) {
|
|
|
|
|
|
differentImpl := func(in, old, new []byte, n int) []byte {
|
|
|
|
|
|
var out Buffer
|
|
|
|
|
|
if n < 0 {
|
|
|
|
|
|
n = math.MaxInt
|
|
|
|
|
|
}
|
|
|
|
|
|
for i := 0; i < len(in); {
|
|
|
|
|
|
if n == 0 {
|
|
|
|
|
|
out.Write(in[i:])
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
if HasPrefix(in[i:], old) {
|
|
|
|
|
|
out.Write(new)
|
|
|
|
|
|
i += len(old)
|
|
|
|
|
|
n--
|
|
|
|
|
|
if len(old) != 0 {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
if i == len(in) {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(old) == 0 {
|
|
|
|
|
|
_, length := utf8.DecodeRune(in[i:])
|
|
|
|
|
|
out.Write(in[i : i+length])
|
|
|
|
|
|
i += length
|
|
|
|
|
|
} else {
|
|
|
|
|
|
out.WriteByte(in[i])
|
|
|
|
|
|
i++
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(old) == 0 && n != 0 {
|
|
|
|
|
|
out.Write(new)
|
|
|
|
|
|
}
|
|
|
|
|
|
return out.Bytes()
|
|
|
|
|
|
}
|
|
|
|
|
|
if simple, replace := differentImpl(in, old, new, n), Replace(in, old, new, n); !slices.Equal(simple, replace) {
|
|
|
|
|
|
t.Errorf("The two implementations do not match %q != %q for Replace(%q, %q, %q, %d)", simple, replace, in, old, new, n)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkReplace(b *testing.B) {
|
|
|
|
|
|
for _, tt := range ReplaceTests {
|
|
|
|
|
|
desc := fmt.Sprintf("%q %q %q %d", tt.in, tt.old, tt.new, tt.n)
|
|
|
|
|
|
var (
|
|
|
|
|
|
in = []byte(tt.in)
|
|
|
|
|
|
old = []byte(tt.old)
|
|
|
|
|
|
new = []byte(tt.new)
|
|
|
|
|
|
)
|
|
|
|
|
|
b.Run(desc, func(b *testing.B) {
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
for b.Loop() {
|
|
|
|
|
|
Replace(in, old, new, tt.n)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-07-20 19:53:59 -07:00
|
|
|
|
type TitleTest struct {
|
|
|
|
|
|
in, out string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var TitleTests = []TitleTest{
|
2010-10-22 10:06:33 -07:00
|
|
|
|
{"", ""},
|
|
|
|
|
|
{"a", "A"},
|
|
|
|
|
|
{" aaa aaa aaa ", " Aaa Aaa Aaa "},
|
|
|
|
|
|
{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
|
|
|
|
|
|
{"123a456", "123a456"},
|
|
|
|
|
|
{"double-blind", "Double-Blind"},
|
|
|
|
|
|
{"ÿøû", "Ÿøû"},
|
2013-12-20 23:19:32 -08:00
|
|
|
|
{"with_underscore", "With_underscore"},
|
|
|
|
|
|
{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
|
2010-07-20 19:53:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestTitle(t *testing.T) {
|
|
|
|
|
|
for _, tt := range TitleTests {
|
|
|
|
|
|
if s := string(Title([]byte(tt.in))); s != tt.out {
|
|
|
|
|
|
t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2011-09-26 19:35:32 -04:00
|
|
|
|
|
2013-09-11 21:20:15 +10:00
|
|
|
|
var ToTitleTests = []TitleTest{
|
|
|
|
|
|
{"", ""},
|
|
|
|
|
|
{"a", "A"},
|
|
|
|
|
|
{" aaa aaa aaa ", " AAA AAA AAA "},
|
|
|
|
|
|
{" Aaa Aaa Aaa ", " AAA AAA AAA "},
|
|
|
|
|
|
{"123a456", "123A456"},
|
|
|
|
|
|
{"double-blind", "DOUBLE-BLIND"},
|
|
|
|
|
|
{"ÿøû", "ŸØÛ"},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestToTitle(t *testing.T) {
|
|
|
|
|
|
for _, tt := range ToTitleTests {
|
|
|
|
|
|
if s := string(ToTitle([]byte(tt.in))); s != tt.out {
|
|
|
|
|
|
t.Errorf("ToTitle(%q) = %q, want %q", tt.in, s, tt.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-09-26 19:35:32 -04:00
|
|
|
|
var EqualFoldTests = []struct {
|
|
|
|
|
|
s, t string
|
|
|
|
|
|
out bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"abc", "abc", true},
|
|
|
|
|
|
{"ABcd", "ABcd", true},
|
|
|
|
|
|
{"123abc", "123ABC", true},
|
|
|
|
|
|
{"αβδ", "ΑΒΔ", true},
|
|
|
|
|
|
{"abc", "xyz", false},
|
|
|
|
|
|
{"abc", "XYZ", false},
|
|
|
|
|
|
{"abcdefghijk", "abcdefghijX", false},
|
|
|
|
|
|
{"abcdefghijk", "abcdefghij\u212A", true},
|
|
|
|
|
|
{"abcdefghijK", "abcdefghij\u212A", true},
|
|
|
|
|
|
{"abcdefghijkz", "abcdefghij\u212Ay", false},
|
|
|
|
|
|
{"abcdefghijKz", "abcdefghij\u212Ay", false},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestEqualFold(t *testing.T) {
|
|
|
|
|
|
for _, tt := range EqualFoldTests {
|
|
|
|
|
|
if out := EqualFold([]byte(tt.s), []byte(tt.t)); out != tt.out {
|
|
|
|
|
|
t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
if out := EqualFold([]byte(tt.t), []byte(tt.s)); out != tt.out {
|
|
|
|
|
|
t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2012-09-18 15:02:08 -04:00
|
|
|
|
|
2021-09-21 10:59:16 -04:00
|
|
|
|
var cutTests = []struct {
|
|
|
|
|
|
s, sep string
|
|
|
|
|
|
before, after string
|
|
|
|
|
|
found bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"abc", "b", "a", "c", true},
|
|
|
|
|
|
{"abc", "a", "", "bc", true},
|
|
|
|
|
|
{"abc", "c", "ab", "", true},
|
|
|
|
|
|
{"abc", "abc", "", "", true},
|
|
|
|
|
|
{"abc", "", "", "abc", true},
|
|
|
|
|
|
{"abc", "d", "abc", "", false},
|
|
|
|
|
|
{"", "d", "", "", false},
|
|
|
|
|
|
{"", "", "", "", true},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestCut(t *testing.T) {
|
|
|
|
|
|
for _, tt := range cutTests {
|
|
|
|
|
|
if before, after, found := Cut([]byte(tt.s), []byte(tt.sep)); string(before) != tt.before || string(after) != tt.after || found != tt.found {
|
|
|
|
|
|
t.Errorf("Cut(%q, %q) = %q, %q, %v, want %q, %q, %v", tt.s, tt.sep, before, after, found, tt.before, tt.after, tt.found)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-05-19 11:57:50 +02:00
|
|
|
|
var cutPrefixTests = []struct {
|
|
|
|
|
|
s, sep string
|
|
|
|
|
|
after string
|
|
|
|
|
|
found bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"abc", "a", "bc", true},
|
|
|
|
|
|
{"abc", "abc", "", true},
|
|
|
|
|
|
{"abc", "", "abc", true},
|
|
|
|
|
|
{"abc", "d", "abc", false},
|
|
|
|
|
|
{"", "d", "", false},
|
|
|
|
|
|
{"", "", "", true},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestCutPrefix(t *testing.T) {
|
|
|
|
|
|
for _, tt := range cutPrefixTests {
|
|
|
|
|
|
if after, found := CutPrefix([]byte(tt.s), []byte(tt.sep)); string(after) != tt.after || found != tt.found {
|
|
|
|
|
|
t.Errorf("CutPrefix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var cutSuffixTests = []struct {
|
|
|
|
|
|
s, sep string
|
2023-01-19 03:12:12 +00:00
|
|
|
|
before string
|
2022-05-19 11:57:50 +02:00
|
|
|
|
found bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"abc", "bc", "a", true},
|
|
|
|
|
|
{"abc", "abc", "", true},
|
|
|
|
|
|
{"abc", "", "abc", true},
|
|
|
|
|
|
{"abc", "d", "abc", false},
|
|
|
|
|
|
{"", "d", "", false},
|
|
|
|
|
|
{"", "", "", true},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestCutSuffix(t *testing.T) {
|
|
|
|
|
|
for _, tt := range cutSuffixTests {
|
2023-01-19 03:12:12 +00:00
|
|
|
|
if before, found := CutSuffix([]byte(tt.s), []byte(tt.sep)); string(before) != tt.before || found != tt.found {
|
|
|
|
|
|
t.Errorf("CutSuffix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, before, found, tt.before, tt.found)
|
2022-05-19 11:57:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-09-11 21:20:15 +10:00
|
|
|
|
func TestBufferGrowNegative(t *testing.T) {
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
if err := recover(); err == nil {
|
2014-05-10 07:13:42 +09:00
|
|
|
|
t.Fatal("Grow(-1) should have panicked")
|
2013-09-11 21:20:15 +10:00
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
var b Buffer
|
|
|
|
|
|
b.Grow(-1)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestBufferTruncateNegative(t *testing.T) {
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
if err := recover(); err == nil {
|
2014-05-10 07:13:42 +09:00
|
|
|
|
t.Fatal("Truncate(-1) should have panicked")
|
2013-09-11 21:20:15 +10:00
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
var b Buffer
|
|
|
|
|
|
b.Truncate(-1)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestBufferTruncateOutOfRange(t *testing.T) {
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
if err := recover(); err == nil {
|
2014-05-10 07:13:42 +09:00
|
|
|
|
t.Fatal("Truncate(20) should have panicked")
|
2013-09-11 21:20:15 +10:00
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
var b Buffer
|
|
|
|
|
|
b.Write(make([]byte, 10))
|
|
|
|
|
|
b.Truncate(20)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-12-28 20:33:05 +11:00
|
|
|
|
var containsTests = []struct {
|
|
|
|
|
|
b, subslice []byte
|
|
|
|
|
|
want bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{[]byte("hello"), []byte("hel"), true},
|
|
|
|
|
|
{[]byte("日本語"), []byte("日本"), true},
|
|
|
|
|
|
{[]byte("hello"), []byte("Hello, world"), false},
|
|
|
|
|
|
{[]byte("東京"), []byte("京東"), false},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestContains(t *testing.T) {
|
|
|
|
|
|
for _, tt := range containsTests {
|
|
|
|
|
|
if got := Contains(tt.b, tt.subslice); got != tt.want {
|
|
|
|
|
|
t.Errorf("Contains(%q, %q) = %v, want %v", tt.b, tt.subslice, got, tt.want)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-04-05 15:43:07 -07:00
|
|
|
|
var ContainsAnyTests = []struct {
|
|
|
|
|
|
b []byte
|
|
|
|
|
|
substr string
|
|
|
|
|
|
expected bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{[]byte(""), "", false},
|
|
|
|
|
|
{[]byte(""), "a", false},
|
|
|
|
|
|
{[]byte(""), "abc", false},
|
|
|
|
|
|
{[]byte("a"), "", false},
|
|
|
|
|
|
{[]byte("a"), "a", true},
|
|
|
|
|
|
{[]byte("aaa"), "a", true},
|
|
|
|
|
|
{[]byte("abc"), "xyz", false},
|
|
|
|
|
|
{[]byte("abc"), "xcz", true},
|
|
|
|
|
|
{[]byte("a☺b☻c☹d"), "uvw☻xyz", true},
|
|
|
|
|
|
{[]byte("aRegExp*"), ".(|)*+?^$[]", true},
|
|
|
|
|
|
{[]byte(dots + dots + dots), " ", false},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestContainsAny(t *testing.T) {
|
|
|
|
|
|
for _, ct := range ContainsAnyTests {
|
|
|
|
|
|
if ContainsAny(ct.b, ct.substr) != ct.expected {
|
|
|
|
|
|
t.Errorf("ContainsAny(%s, %s) = %v, want %v",
|
|
|
|
|
|
ct.b, ct.substr, !ct.expected, ct.expected)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-04-07 23:22:30 -07:00
|
|
|
|
var ContainsRuneTests = []struct {
|
|
|
|
|
|
b []byte
|
|
|
|
|
|
r rune
|
|
|
|
|
|
expected bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{[]byte(""), 'a', false},
|
|
|
|
|
|
{[]byte("a"), 'a', true},
|
|
|
|
|
|
{[]byte("aaa"), 'a', true},
|
|
|
|
|
|
{[]byte("abc"), 'y', false},
|
|
|
|
|
|
{[]byte("abc"), 'c', true},
|
|
|
|
|
|
{[]byte("a☺b☻c☹d"), 'x', false},
|
|
|
|
|
|
{[]byte("a☺b☻c☹d"), '☻', true},
|
|
|
|
|
|
{[]byte("aRegExp*"), '*', true},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestContainsRune(t *testing.T) {
|
|
|
|
|
|
for _, ct := range ContainsRuneTests {
|
|
|
|
|
|
if ContainsRune(ct.b, ct.r) != ct.expected {
|
|
|
|
|
|
t.Errorf("ContainsRune(%q, %q) = %v, want %v",
|
|
|
|
|
|
ct.b, ct.r, !ct.expected, ct.expected)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-03 16:23:16 +08:00
|
|
|
|
func TestContainsFunc(t *testing.T) {
|
|
|
|
|
|
for _, ct := range ContainsRuneTests {
|
|
|
|
|
|
if ContainsFunc(ct.b, func(r rune) bool {
|
|
|
|
|
|
return ct.r == r
|
|
|
|
|
|
}) != ct.expected {
|
|
|
|
|
|
t.Errorf("ContainsFunc(%q, func(%q)) = %v, want %v",
|
|
|
|
|
|
ct.b, ct.r, !ct.expected, ct.expected)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-09-18 15:02:08 -04:00
|
|
|
|
var makeFieldsInput = func() []byte {
|
|
|
|
|
|
x := make([]byte, 1<<20)
|
2012-10-30 13:38:01 -07:00
|
|
|
|
// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
|
2025-05-14 12:46:28 -07:00
|
|
|
|
r := rand.New(rand.NewSource(99))
|
2012-09-18 15:02:08 -04:00
|
|
|
|
for i := range x {
|
2025-05-14 12:46:28 -07:00
|
|
|
|
switch r.Intn(10) {
|
2012-09-18 15:02:08 -04:00
|
|
|
|
case 0:
|
|
|
|
|
|
x[i] = ' '
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
if i > 0 && x[i-1] == 'x' {
|
|
|
|
|
|
copy(x[i-1:], "χ")
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
fallthrough
|
|
|
|
|
|
default:
|
|
|
|
|
|
x[i] = 'x'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return x
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-12 10:20:30 +02:00
|
|
|
|
var makeFieldsInputASCII = func() []byte {
|
|
|
|
|
|
x := make([]byte, 1<<20)
|
|
|
|
|
|
// Input is ~10% space, rest ASCII non-space.
|
2025-05-14 12:46:28 -07:00
|
|
|
|
r := rand.New(rand.NewSource(99))
|
2017-08-12 10:20:30 +02:00
|
|
|
|
for i := range x {
|
2025-05-14 12:46:28 -07:00
|
|
|
|
if r.Intn(10) == 0 {
|
2017-08-12 10:20:30 +02:00
|
|
|
|
x[i] = ' '
|
|
|
|
|
|
} else {
|
|
|
|
|
|
x[i] = 'x'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return x
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var bytesdata = []struct {
|
|
|
|
|
|
name string
|
|
|
|
|
|
data []byte
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"ASCII", makeFieldsInputASCII()},
|
|
|
|
|
|
{"Mixed", makeFieldsInput()},
|
|
|
|
|
|
}
|
2012-09-18 15:02:08 -04:00
|
|
|
|
|
|
|
|
|
|
func BenchmarkFields(b *testing.B) {
|
2017-08-12 10:20:30 +02:00
|
|
|
|
for _, sd := range bytesdata {
|
|
|
|
|
|
b.Run(sd.name, func(b *testing.B) {
|
|
|
|
|
|
for j := 1 << 4; j <= 1<<20; j <<= 4 {
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d", j), func(b *testing.B) {
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
b.SetBytes(int64(j))
|
|
|
|
|
|
data := sd.data[:j]
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Fields(data)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2012-09-18 15:02:08 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkFieldsFunc(b *testing.B) {
|
2017-08-12 10:20:30 +02:00
|
|
|
|
for _, sd := range bytesdata {
|
|
|
|
|
|
b.Run(sd.name, func(b *testing.B) {
|
|
|
|
|
|
for j := 1 << 4; j <= 1<<20; j <<= 4 {
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d", j), func(b *testing.B) {
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
b.SetBytes(int64(j))
|
|
|
|
|
|
data := sd.data[:j]
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
FieldsFunc(data, unicode.IsSpace)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2012-09-18 15:02:08 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2013-02-07 16:00:06 -08:00
|
|
|
|
|
|
|
|
|
|
func BenchmarkTrimSpace(b *testing.B) {
|
2018-12-06 08:53:29 -05:00
|
|
|
|
tests := []struct {
|
|
|
|
|
|
name string
|
|
|
|
|
|
input []byte
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"NoTrim", []byte("typical")},
|
|
|
|
|
|
{"ASCII", []byte(" foo bar ")},
|
|
|
|
|
|
{"SomeNonASCII", []byte(" \u2000\t\r\n x\t\t\r\r\ny\n \u3000 ")},
|
|
|
|
|
|
{"JustNonASCII", []byte("\u2000\u2000\u2000☺☺☺☺\u3000\u3000\u3000")},
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
|
|
b.Run(test.name, func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
TrimSpace(test.input)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2013-02-07 16:00:06 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-06-11 19:03:59 -07:00
|
|
|
|
|
2018-10-13 22:40:23 +02:00
|
|
|
|
func BenchmarkToValidUTF8(b *testing.B) {
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
|
name string
|
|
|
|
|
|
input []byte
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"Valid", []byte("typical")},
|
|
|
|
|
|
{"InvalidASCII", []byte("foo\xffbar")},
|
|
|
|
|
|
{"InvalidNonASCII", []byte("日本語\xff日本語")},
|
|
|
|
|
|
}
|
|
|
|
|
|
replacement := []byte("\uFFFD")
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
|
|
b.Run(test.name, func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
ToValidUTF8(test.input, replacement)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-07 13:38:52 +02:00
|
|
|
|
func makeBenchInputHard() []byte {
|
|
|
|
|
|
tokens := [...]string{
|
|
|
|
|
|
"<a>", "<p>", "<b>", "<strong>",
|
|
|
|
|
|
"</a>", "</p>", "</b>", "</strong>",
|
|
|
|
|
|
"hello", "world",
|
|
|
|
|
|
}
|
|
|
|
|
|
x := make([]byte, 0, 1<<20)
|
2025-05-14 12:46:28 -07:00
|
|
|
|
r := rand.New(rand.NewSource(99))
|
2017-02-07 13:38:52 +02:00
|
|
|
|
for {
|
2025-05-14 12:46:28 -07:00
|
|
|
|
i := r.Intn(len(tokens))
|
2017-02-07 13:38:52 +02:00
|
|
|
|
if len(x)+len(tokens[i]) >= 1<<20 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
x = append(x, tokens[i]...)
|
|
|
|
|
|
}
|
|
|
|
|
|
return x
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var benchInputHard = makeBenchInputHard()
|
|
|
|
|
|
|
2019-03-15 11:29:03 +01:00
|
|
|
|
func benchmarkIndexHard(b *testing.B, sep []byte) {
|
2023-11-02 00:18:59 -04:00
|
|
|
|
n := Index(benchInputHard, sep)
|
|
|
|
|
|
if n < 0 {
|
|
|
|
|
|
n = len(benchInputHard)
|
|
|
|
|
|
}
|
|
|
|
|
|
b.SetBytes(int64(n))
|
2019-03-15 11:29:03 +01:00
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Index(benchInputHard, sep)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-08 11:36:31 +01:00
|
|
|
|
func benchmarkLastIndexHard(b *testing.B, sep []byte) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
LastIndex(benchInputHard, sep)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-15 11:29:03 +01:00
|
|
|
|
func benchmarkCountHard(b *testing.B, sep []byte) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Count(benchInputHard, sep)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkIndexHard1(b *testing.B) { benchmarkIndexHard(b, []byte("<>")) }
|
|
|
|
|
|
func BenchmarkIndexHard2(b *testing.B) { benchmarkIndexHard(b, []byte("</pre>")) }
|
|
|
|
|
|
func BenchmarkIndexHard3(b *testing.B) { benchmarkIndexHard(b, []byte("<b>hello world</b>")) }
|
|
|
|
|
|
func BenchmarkIndexHard4(b *testing.B) {
|
|
|
|
|
|
benchmarkIndexHard(b, []byte("<pre><b>hello</b><strong>world</strong></pre>"))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-08 11:36:31 +01:00
|
|
|
|
func BenchmarkLastIndexHard1(b *testing.B) { benchmarkLastIndexHard(b, []byte("<>")) }
|
|
|
|
|
|
func BenchmarkLastIndexHard2(b *testing.B) { benchmarkLastIndexHard(b, []byte("</pre>")) }
|
|
|
|
|
|
func BenchmarkLastIndexHard3(b *testing.B) { benchmarkLastIndexHard(b, []byte("<b>hello world</b>")) }
|
|
|
|
|
|
|
2019-03-15 11:29:03 +01:00
|
|
|
|
func BenchmarkCountHard1(b *testing.B) { benchmarkCountHard(b, []byte("<>")) }
|
|
|
|
|
|
func BenchmarkCountHard2(b *testing.B) { benchmarkCountHard(b, []byte("</pre>")) }
|
|
|
|
|
|
func BenchmarkCountHard3(b *testing.B) { benchmarkCountHard(b, []byte("<b>hello world</b>")) }
|
|
|
|
|
|
|
2017-02-07 13:38:52 +02:00
|
|
|
|
func BenchmarkSplitEmptySeparator(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Split(benchInputHard, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkSplitSingleByteSeparator(b *testing.B) {
|
|
|
|
|
|
sep := []byte("/")
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Split(benchInputHard, sep)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkSplitMultiByteSeparator(b *testing.B) {
|
|
|
|
|
|
sep := []byte("hello")
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Split(benchInputHard, sep)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkSplitNSingleByteSeparator(b *testing.B) {
|
|
|
|
|
|
sep := []byte("/")
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
SplitN(benchInputHard, sep, 10)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkSplitNMultiByteSeparator(b *testing.B) {
|
|
|
|
|
|
sep := []byte("hello")
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
SplitN(benchInputHard, sep, 10)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-06-11 19:03:59 -07:00
|
|
|
|
func BenchmarkRepeat(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Repeat([]byte("-"), 80)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2015-07-02 11:43:46 -07:00
|
|
|
|
|
2022-07-22 14:18:33 +09:00
|
|
|
|
func BenchmarkRepeatLarge(b *testing.B) {
|
|
|
|
|
|
s := Repeat([]byte("@"), 8*1024)
|
|
|
|
|
|
for j := 8; j <= 30; j++ {
|
|
|
|
|
|
for _, k := range []int{1, 16, 4097} {
|
|
|
|
|
|
s := s[:k]
|
|
|
|
|
|
n := (1 << j) / k
|
|
|
|
|
|
if n == 0 {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d/%d", 1<<j, k), func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Repeat(s, n)
|
|
|
|
|
|
}
|
|
|
|
|
|
b.SetBytes(int64(n * len(s)))
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
func BenchmarkBytesCompare(b *testing.B) {
|
|
|
|
|
|
for n := 1; n <= 2048; n <<= 1 {
|
|
|
|
|
|
b.Run(fmt.Sprint(n), func(b *testing.B) {
|
|
|
|
|
|
var x = make([]byte, n)
|
|
|
|
|
|
var y = make([]byte, n)
|
2015-07-02 11:43:46 -07:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
|
|
x[i] = 'a'
|
|
|
|
|
|
}
|
2015-07-02 11:43:46 -07:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
|
|
y[i] = 'a'
|
|
|
|
|
|
}
|
2015-07-02 11:43:46 -07:00
|
|
|
|
|
2016-05-26 10:54:25 +02:00
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Compare(x, y)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
|
|
|
|
|
|
func BenchmarkIndexAnyASCII(b *testing.B) {
|
strings, bytes: improve IndexAny and LastIndexAny performance
For the case of a pattern containing multi-byte rune, the time complexity of the
previous algorithm is O(nm), and if both input arguments are long, the search
performance will be poor. This CL improves the searching performance for these
cases by using IndexRune, which is mainly implemented with IndexByte and Index.
As IndexByte and Index are specially optimized with some powerful instructions
for short patterns (an UTF8 rune is 1 to 4 bytes), so they can help to reduce the
runtime complexity of IndexAny and LastIndexAny.
Another optimization method is using hash table, however, the actual test results
show that using indexrune is better, and the space complexity is lower.
There are two fast paths in IndexAny and LastIndexAny for cases where the length
of the input arguements are 1, and their locations are not exactly the same, which
is determined based on the actual test results.
Benchmarks on arm64 and amd64:
name old time/op new time/op delta
pkg:strings goos:linux goarch:arm64
IndexAnyASCII/1:1-8 23.7ns ± 3% 28.5ns ± 0% +20.15% (p=0.008 n=5+5)
IndexAnyASCII/1:2-8 18.0ns ± 0% 33.1ns ± 0% +83.67% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 20.0ns ± 0% 36.0ns ± 0% +80.00% (p=0.029 n=4+4)
IndexAnyASCII/1:8-8 36.1ns ± 0% 36.0ns ± 0% ~ (p=0.095 n=5+4)
IndexAnyASCII/1:16-8 48.1ns ± 0% 36.0ns ± 0% -25.19% (p=0.029 n=4+4)
IndexAnyASCII/1:32-8 72.1ns ± 0% 36.0ns ± 0% -50.01% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 120ns ± 0% 39ns ± 0% -67.83% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.0ns ± 0% 28.5ns ± 0% -60.95% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 76.8ns ± 0% 77.0ns ± 0% ~ (p=1.000 n=5+5)
IndexAnyASCII/16:4-8 83.2ns ± 1% 83.0ns ± 0% ~ (p=0.770 n=5+5)
IndexAnyASCII/16:8-8 111ns ± 1% 107ns ± 0% -3.25% (p=0.008 n=5+5)
IndexAnyASCII/16:16-8 139ns ± 1% 137ns ± 0% -1.58% (p=0.008 n=5+5)
IndexAnyASCII/16:32-8 199ns ± 1% 197ns ± 0% -1.20% (p=0.008 n=5+5)
IndexAnyASCII/16:64-8 307ns ± 0% 313ns ± 0% +1.82% (p=0.016 n=5+4)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 0% -90.31% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 678ns ± 0% 683ns ± 0% +0.68% (p=0.008 n=5+5)
IndexAnyASCII/256:4-8 685ns ± 0% 683ns ± 0% -0.29% (p=0.000 n=5+4)
IndexAnyASCII/256:8-8 711ns ± 0% 708ns ± 0% -0.48% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 740ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:32-8 799ns ± 0% 798ns ± 0% -0.18% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 910ns ± 0% 914ns ± 0% +0.44% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.1ns ± 0% 19.0ns ± 0% -29.79% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.1ns ± 0% 33.0ns ± 0% -25.17% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 46.1ns ± 0% 33.1ns ± 0% -28.29% (p=0.016 n=4+5)
IndexAnyUTF8/1:8-8 85.1ns ± 0% 33.0ns ± 0% -61.18% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 36ns ± 0% -67.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:32-8 188ns ± 0% 36ns ± 0% -80.85% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 332ns ± 0% 39ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/16:1-8 293ns ± 0% 54ns ± 0% -81.56% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 349ns ± 0% -37.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 546ns ± 1% 349ns ± 0% -36.10% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.22µs ± 0% 0.35µs ± 0% -71.39% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.63µs ± 1% 0.42µs ± 0% -73.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.87µs ± 0% 0.42µs ± 0% -85.22% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.47µs ± 0% -90.98% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.26µs ± 0% 0.47µs ± 0% -88.85% (p=0.000 n=4+5)
IndexAnyUTF8/256:2-8 8.62µs ± 0% 5.15µs ± 0% -40.21% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-8 8.25µs ± 0% 5.15µs ± 0% -37.50% (p=0.016 n=5+4)
IndexAnyUTF8/256:8-8 19.2µs ± 1% 5.2µs ± 0% -73.08% (p=0.016 n=5+4)
IndexAnyUTF8/256:16-8 25.6µs ± 1% 6.3µs ± 0% -75.32% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.6µs ± 0% 6.3µs ± 0% -86.15% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-8 82.4µs ± 0% 7.0µs ± 0% -91.53% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 33.5ns ± 0% +45.65% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 33.5ns ± 0% +36.73% (p=0.016 n=4+5)
LastIndexAnyASCII/1:4-8 27.5ns ± 0% 35.5ns ± 0% +29.09% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-8 44.5ns ± 0% 35.5ns ± 0% -20.13% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-8 56.5ns ± 0% 35.5ns ± 0% -37.15% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 80.3ns ± 0% 35.5ns ± 0% -55.79% (p=0.000 n=5+4)
LastIndexAnyASCII/1:64-8 129ns ± 0% 40ns ± 0% -68.85% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.8ns ± 0% 72.7ns ± 0% -0.19% (p=0.016 n=4+5)
LastIndexAnyASCII/16:2-8 75.4ns ± 0% 75.1ns ± 0% ~ (p=0.127 n=5+5)
LastIndexAnyASCII/16:4-8 81.9ns ± 1% 80.2ns ± 0% -2.00% (p=0.008 n=5+5)
LastIndexAnyASCII/16:8-8 110ns ± 1% 108ns ± 0% -1.46% (p=0.008 n=5+5)
LastIndexAnyASCII/16:16-8 138ns ± 1% 134ns ± 0% -3.18% (p=0.008 n=5+5)
LastIndexAnyASCII/16:32-8 198ns ± 0% 197ns ± 0% -0.51% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 313ns ± 0% +1.30% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-8 652ns ± 0% 653ns ± 0% +0.21% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 656ns ± 0% 656ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:4-8 663ns ± 0% 663ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/256:8-8 691ns ± 0% 690ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/256:16-8 719ns ± 0% 715ns ± 0% -0.53% (p=0.000 n=5+4)
LastIndexAnyASCII/256:32-8 779ns ± 0% 780ns ± 0% +0.13% (p=0.029 n=4+4)
LastIndexAnyASCII/256:64-8 890ns ± 0% 894ns ± 0% +0.45% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-8 31.6ns ± 0% 33.5ns ± 0% +6.01% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 33.5ns ± 0% -30.99% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-8 48.6ns ± 0% 33.5ns ± 0% -31.13% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:8-8 89.6ns ± 0% 33.5ns ± 0% -62.56% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 113ns ± 1% 36ns ± 0% -68.47% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 190ns ± 0% 36ns ± 0% -81.26% (p=0.029 n=4+4)
LastIndexAnyUTF8/1:64-8 327ns ± 0% 40ns ± 0% -87.77% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-8 364ns ± 0% 158ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/16:2-8 636ns ± 0% 472ns ± 0% -25.79% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:4-8 630ns ± 0% 472ns ± 0% -25.03% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.28µs ± 0% 0.47µs ± 0% -63.09% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.53µs ± 0% -68.39% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-8 2.88µs ± 0% 0.53µs ± 0% -81.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-8 5.08µs ± 0% 0.57µs ± 0% -88.79% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.41µs ± 0% 2.03µs ± 0% -62.46% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:2-8 9.77µs ± 0% 7.14µs ± 0% -26.97% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.63µs ± 0% 7.14µs ± 0% -25.86% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.0µs ± 0% 7.1µs ± 0% -64.30% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.1µs ± 1% 8.0µs ± 0% -69.40% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 45.6µs ± 1% 8.0µs ± 0% -82.51% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 80.8µs ± 0% 8.6µs ± 0% -89.33% (p=0.016 n=5+4)
pkg:bytes goos:linux goarch:arm64
IndexAnyASCII/1:1-8 26.2ns ± 1% 26.5ns ± 0% +1.30% (p=0.016 n=5+4)
IndexAnyASCII/1:2-8 18.5ns ± 0% 26.5ns ± 0% +43.24% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 21.0ns ± 0% 26.5ns ± 0% +26.38% (p=0.008 n=5+5)
IndexAnyASCII/1:8-8 37.5ns ± 0% 26.5ns ± 0% -29.33% (p=0.000 n=5+4)
IndexAnyASCII/1:16-8 49.6ns ± 0% 26.5ns ± 0% -46.49% (p=0.008 n=5+5)
IndexAnyASCII/1:32-8 73.6ns ± 0% 30.1ns ± 0% -59.16% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 122ns ± 0% 33ns ± 0% -73.23% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.7ns ± 0% 33.4ns ± 0% -54.71% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 79.1ns ± 0% 78.9ns ± 0% -0.30% (p=0.016 n=4+5)
IndexAnyASCII/16:4-8 84.8ns ± 0% 86.1ns ± 0% +1.58% (p=0.016 n=5+4)
IndexAnyASCII/16:8-8 111ns ± 0% 111ns ± 0% ~ (all equal)
IndexAnyASCII/16:16-8 139ns ± 0% 144ns ± 0% +3.60% (p=0.016 n=4+5)
IndexAnyASCII/16:32-8 196ns ± 0% 207ns ± 0% +5.61% (p=0.016 n=5+4)
IndexAnyASCII/16:64-8 311ns ± 0% 320ns ± 0% +2.89% (p=0.016 n=4+5)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 1% -90.35% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 680ns ± 0% 680ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:4-8 686ns ± 0% 687ns ± 0% ~ (p=0.167 n=5+5)
IndexAnyASCII/256:8-8 713ns ± 0% 712ns ± 0% -0.14% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 744ns ± 0% +0.54% (p=0.016 n=5+4)
IndexAnyASCII/256:32-8 797ns ± 0% 808ns ± 0% +1.43% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 912ns ± 0% 921ns ± 0% +0.99% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.5ns ± 0% 26.5ns ± 0% -3.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.5ns ± 0% 26.5ns ± 0% -40.50% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 45.6ns ± 0% 26.5ns ± 0% -41.89% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-8 85.8ns ± 1% 26.5ns ± 0% -69.11% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 26ns ± 0% -76.00% (p=0.016 n=5+4)
IndexAnyUTF8/1:32-8 188ns ± 0% 30ns ± 0% -84.04% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 333ns ± 0% 33ns ± 0% -90.20% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-8 294ns ± 0% 235ns ± 0% -20.07% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 309ns ± 0% -45.12% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 558ns ± 1% 309ns ± 0% -44.60% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.23µs ± 0% 0.31µs ± 0% -74.79% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.62µs ± 2% 0.31µs ± 0% -80.93% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.86µs ± 0% 0.38µs ± 0% -86.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.42µs ± 0% -91.86% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.27µs ± 1% 3.30µs ± 1% -22.75% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-8 8.61µs ± 0% 4.45µs ± 0% -48.31% (p=0.016 n=4+5)
IndexAnyUTF8/256:4-8 8.44µs ± 0% 4.45µs ± 0% -47.23% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-8 19.2µs ± 0% 4.5µs ± 0% -76.78% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-8 25.6µs ± 0% 4.5µs ± 0% -82.63% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.4µs ± 0% 5.5µs ± 0% -87.85% (p=0.016 n=4+5)
IndexAnyUTF8/256:64-8 82.5µs ± 0% 6.2µs ± 0% -92.49% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 26.5ns ± 0% +15.02% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 26.5ns ± 0% +8.16% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-8 27.8ns ± 0% 26.5ns ± 0% -4.68% (p=0.029 n=4+4)
LastIndexAnyASCII/1:8-8 45.1ns ± 1% 26.5ns ± 0% -41.29% (p=0.000 n=5+4)
LastIndexAnyASCII/1:16-8 57.1ns ± 0% 26.5ns ± 0% -53.61% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 81.5ns ± 0% 30.0ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:64-8 129ns ± 0% 32ns ± 0% -74.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.6ns ± 0% 72.1ns ± 0% -0.63% (p=0.000 n=4+5)
LastIndexAnyASCII/16:2-8 77.2ns ± 0% 77.2ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:4-8 83.1ns ± 0% 83.2ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/16:8-8 109ns ± 1% 108ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:16-8 136ns ± 0% 136ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:32-8 195ns ± 0% 197ns ± 0% +0.82% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 309ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:1-8 653ns ± 0% 657ns ± 0% +0.61% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 659ns ± 0% 658ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/256:4-8 664ns ± 0% 663ns ± 0% ~ (p=0.095 n=5+4)
LastIndexAnyASCII/256:8-8 698ns ± 0% 689ns ± 0% -1.29% (p=0.008 n=5+5)
LastIndexAnyASCII/256:16-8 726ns ± 0% 717ns ± 0% -1.24% (p=0.008 n=5+5)
LastIndexAnyASCII/256:32-8 777ns ± 0% 779ns ± 0% ~ (p=0.079 n=5+4)
LastIndexAnyASCII/256:64-8 889ns ± 0% 890ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyUTF8/1:1-8 32.1ns ± 0% 26.5ns ± 0% -17.45% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 26.5ns ± 0% -45.52% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:4-8 49.6ns ± 0% 26.5ns ± 0% -46.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-8 91.9ns ± 0% 26.5ns ± 0% -71.18% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 114ns ± 1% 26ns ± 0% -76.84% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 203ns ± 6% 30ns ± 0% -85.25% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-8 330ns ± 0% 33ns ± 0% -90.14% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:1-8 365ns ± 0% 164ns ± 0% -55.04% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-8 638ns ± 0% 296ns ± 0% -53.58% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-8 634ns ± 0% 296ns ± 0% -53.31% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.30µs ± 0% 0.30µs ± 0% -77.18% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.30µs ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-8 2.90µs ± 0% 0.38µs ± 0% -87.00% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:64-8 5.10µs ± 0% 0.42µs ± 0% -91.78% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.42µs ± 0% 2.12µs ± 0% -60.92% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-8 9.79µs ± 0% 4.26µs ± 0% -56.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.66µs ± 0% 4.26µs ± 0% -55.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.4µs ± 0% 4.3µs ± 0% -79.10% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.0µs ± 1% 4.3µs ± 0% -83.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 46.0µs ± 0% 5.5µs ± 0% -88.09% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 81.1µs ± 0% 6.2µs ± 0% -92.38% (p=0.008 n=5+5)
name old time/op new time/op delta
pkg:strings goos:linux goarch:amd64
IndexAnyASCII/1:1-48 10.0ns ± 0% 13.3ns ± 0% +33.00% (p=0.008 n=5+5)
IndexAnyASCII/1:2-48 11.0ns ± 0% 15.5ns ± 0% +40.55% (p=0.016 n=4+5)
IndexAnyASCII/1:4-48 12.9ns ± 0% 15.4ns ± 0% +19.69% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 18.6ns ± 0% 15.5ns ± 0% -16.45% (p=0.000 n=4+5)
IndexAnyASCII/1:16-48 30.1ns ± 0% 16.9ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/1:32-48 53.1ns ± 0% 18.6ns ± 0% -64.95% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 98.9ns ± 0% 17.4ns ± 0% -82.41% (p=0.000 n=5+4)
IndexAnyASCII/16:1-48 35.0ns ± 0% 14.2ns ± 0% -59.47% (p=0.000 n=5+4)
IndexAnyASCII/16:2-48 35.5ns ± 0% 35.6ns ± 0% ~ (p=0.238 n=5+4)
IndexAnyASCII/16:4-48 40.8ns ± 0% 40.7ns ± 1% ~ (p=0.643 n=5+5)
IndexAnyASCII/16:8-48 50.8ns ± 0% 50.9ns ± 1% ~ (p=1.000 n=4+5)
IndexAnyASCII/16:16-48 64.0ns ± 1% 64.5ns ± 1% ~ (p=0.071 n=5+5)
IndexAnyASCII/16:32-48 98.3ns ± 0% 100.8ns ± 1% +2.52% (p=0.008 n=5+5)
IndexAnyASCII/16:64-48 156ns ± 0% 157ns ± 0% ~ (p=0.238 n=4+5)
IndexAnyASCII/256:1-48 299ns ± 0% 24ns ± 3% -92.12% (p=0.008 n=5+5)
IndexAnyASCII/256:2-48 303ns ± 0% 304ns ± 0% ~ (p=0.762 n=5+5)
IndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.476 n=5+5)
IndexAnyASCII/256:8-48 321ns ± 0% 321ns ± 0% ~ (p=0.429 n=4+5)
IndexAnyASCII/256:16-48 334ns ± 0% 335ns ± 0% ~ (p=0.079 n=5+4)
IndexAnyASCII/256:32-48 367ns ± 0% 365ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/256:64-48 431ns ± 1% 421ns ± 0% -2.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.2ns ± 0% 10.8ns ± 0% -37.21% (p=0.029 n=4+4)
IndexAnyUTF8/1:2-48 26.7ns ± 0% 15.6ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:4-48 28.2ns ± 0% 15.6ns ± 0% -44.68% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-48 48.8ns ± 0% 15.6ns ± 0% -68.03% (p=0.029 n=4+4)
IndexAnyUTF8/1:16-48 58.3ns ± 0% 16.2ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:32-48 103ns ± 0% 18ns ± 0% -82.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 182ns ± 0% 17ns ± 0% -90.53% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 197ns ± 0% 25ns ± 0% -87.34% (p=0.000 n=5+4)
IndexAnyUTF8/16:2-48 348ns ± 0% 163ns ± 0% -53.11% (p=0.000 n=5+4)
IndexAnyUTF8/16:4-48 374ns ± 0% 163ns ± 0% -56.37% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-48 716ns ± 0% 163ns ± 0% -77.22% (p=0.000 n=5+4)
IndexAnyUTF8/16:16-48 859ns ± 0% 175ns ± 0% -79.63% (p=0.000 n=5+4)
IndexAnyUTF8/16:32-48 1.58µs ± 0% 0.20µs ± 0% -87.01% (p=0.029 n=4+4)
IndexAnyUTF8/16:64-48 2.84µs ± 0% 0.19µs ± 1% -93.34% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.61µs ± 0% 0.27µs ± 0% -89.81% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 4.95µs ± 0% 2.23µs ± 0% -54.91% (p=0.016 n=5+4)
IndexAnyUTF8/256:4-48 5.55µs ± 0% 2.23µs ± 0% -59.72% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.2µs ± 0% -79.39% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 13.1µs ± 0% 2.5µs ± 0% -81.21% (p=0.016 n=4+5)
IndexAnyUTF8/256:32-48 24.7µs ± 0% 2.8µs ± 0% -88.49% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-48 45.0µs ± 0% 2.6µs ± 1% -94.23% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-48 13.9ns ± 0% 15.2ns ± 0% +9.35% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-48 14.4ns ± 0% 15.2ns ± 0% +5.56% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-48 16.7ns ± 0% 15.2ns ± 0% -8.98% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-48 24.0ns ± 0% 15.2ns ± 0% -36.67% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-48 35.6ns ± 0% 15.0ns ± 0% -57.82% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-48 68.9ns ± 0% 16.7ns ± 0% -75.75% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 104ns ± 0% 17ns ± 1% -83.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-48 35.0ns ± 0% 35.0ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 35.6ns ± 0% 35.6ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:4-48 41.0ns ± 0% 40.8ns ± 0% -0.49% (p=0.032 n=5+5)
LastIndexAnyASCII/16:8-48 50.9ns ± 0% 50.7ns ± 1% ~ (p=0.397 n=5+5)
LastIndexAnyASCII/16:16-48 64.3ns ± 1% 64.4ns ± 1% ~ (p=1.000 n=4+5)
LastIndexAnyASCII/16:32-48 100ns ± 0% 100ns ± 0% +0.38% (p=0.016 n=4+5)
LastIndexAnyASCII/16:64-48 157ns ± 1% 163ns ± 0% +3.82% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-48 302ns ± 0% 300ns ± 0% -0.53% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 305ns ± 0% 303ns ± 0% -0.66% (p=0.000 n=5+4)
LastIndexAnyASCII/256:4-48 313ns ± 0% 307ns ± 0% -2.04% (p=0.000 n=4+5)
LastIndexAnyASCII/256:8-48 323ns ± 0% 315ns ± 0% -2.48% (p=0.029 n=4+4)
LastIndexAnyASCII/256:16-48 333ns ± 0% 332ns ± 0% -0.30% (p=0.048 n=5+5)
LastIndexAnyASCII/256:32-48 366ns ± 0% 367ns ± 0% ~ (p=0.238 n=4+5)
LastIndexAnyASCII/256:64-48 430ns ± 0% 430ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyUTF8/1:1-48 21.1ns ± 0% 13.9ns ± 0% -34.00% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 29.5ns ± 0% 13.9ns ± 0% -52.95% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 31.6ns ± 0% 13.9ns ± 0% -55.96% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-48 51.1ns ± 0% 13.9ns ± 0% -72.81% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 58.9ns ± 0% 14.6ns ± 0% -75.23% (p=0.016 n=5+4)
LastIndexAnyUTF8/1:32-48 103ns ± 0% 16ns ± 1% -84.12% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 177ns ± 0% 17ns ± 1% -90.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 275ns ± 1% 105ns ± 0% -61.85% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:2-48 406ns ± 0% 216ns ± 0% -46.70% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 458ns ± 0% 216ns ± 0% -52.75% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:8-48 753ns ± 0% 216ns ± 0% -71.31% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:16-48 902ns ± 0% 221ns ± 0% -75.50% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-48 1.57µs ± 0% 0.24µs ± 0% -84.46% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-48 2.77µs ± 0% 0.24µs ± 0% -91.22% (p=0.000 n=5+4)
LastIndexAnyUTF8/256:1-48 4.06µs ± 0% 1.53µs ± 0% -62.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.92µs ± 0% 3.04µs ± 0% -48.55% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:4-48 6.82µs ± 0% 3.04µs ± 0% -55.34% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.5µs ± 0% 3.0µs ± 0% -73.48% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 14.1µs ± 0% 3.1µs ± 0% -77.85% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-48 24.5µs ± 0% 3.5µs ± 0% -85.85% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:64-48 44.0µs ± 0% 3.5µs ± 0% -92.12% (p=0.008 n=5+5)
pkg:bytes goos:linux goarch:amd64
IndexAnyASCII/1:1-48 9.56ns ± 0% 11.00ns ± 0% +15.06% (p=0.016 n=5+4)
IndexAnyASCII/1:2-48 11.0ns ± 0% 10.8ns ± 2% -1.64% (p=0.048 n=5+5)
IndexAnyASCII/1:4-48 13.9ns ± 0% 11.0ns ± 1% -21.15% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 19.6ns ± 0% 10.8ns ± 3% -44.90% (p=0.008 n=5+5)
IndexAnyASCII/1:16-48 31.1ns ± 0% 11.5ns ± 0% -63.02% (p=0.008 n=5+5)
IndexAnyASCII/1:32-48 54.0ns ± 0% 11.8ns ± 0% -78.15% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 100ns ± 0% 13ns ± 0% -86.89% (p=0.008 n=5+5)
IndexAnyASCII/16:1-48 35.5ns ± 0% 14.8ns ± 0% -58.26% (p=0.008 n=5+5)
IndexAnyASCII/16:2-48 36.2ns ± 1% 36.0ns ± 1% ~ (p=0.087 n=5+5)
IndexAnyASCII/16:4-48 40.3ns ± 1% 39.7ns ± 4% ~ (p=0.175 n=4+5)
IndexAnyASCII/16:8-48 48.7ns ± 5% 45.8ns ± 0% -6.02% (p=0.016 n=5+4)
IndexAnyASCII/16:16-48 64.1ns ±11% 62.1ns ± 1% ~ (p=0.143 n=5+5)
IndexAnyASCII/16:32-48 97.9ns ± 1% 98.3ns ± 1% ~ (p=0.294 n=5+5)
IndexAnyASCII/16:64-48 163ns ± 0% 157ns ± 0% -3.68% (p=0.008 n=5+5)
IndexAnyASCII/256:1-48 389ns ± 0% 25ns ± 0% -93.65% (p=0.000 n=5+4)
IndexAnyASCII/256:2-48 391ns ± 0% 307ns ± 0% -21.48% (p=0.000 n=5+4)
IndexAnyASCII/256:4-48 394ns ± 0% 323ns ± 0% -17.92% (p=0.008 n=5+5)
IndexAnyASCII/256:8-48 402ns ± 0% 323ns ± 0% -19.51% (p=0.008 n=5+5)
IndexAnyASCII/256:16-48 414ns ± 0% 334ns ± 0% -19.32% (p=0.016 n=4+5)
IndexAnyASCII/256:32-48 446ns ± 0% 367ns ± 0% -17.75% (p=0.016 n=5+4)
IndexAnyASCII/256:64-48 511ns ± 0% 424ns ± 0% -17.02% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.4ns ± 0% 11.0ns ± 0% -36.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-48 27.3ns ± 1% 11.0ns ± 0% -59.74% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-48 28.7ns ± 0% 11.0ns ± 0% -61.73% (p=0.008 n=5+5)
IndexAnyUTF8/1:8-48 49.2ns ± 0% 11.0ns ± 0% -77.66% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-48 56.0ns ± 0% 11.5ns ± 0% -79.46% (p=0.000 n=5+4)
IndexAnyUTF8/1:32-48 102ns ± 0% 12ns ± 0% -88.24% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 177ns ± 0% 13ns ± 0% -92.51% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 212ns ± 0% 112ns ± 0% -47.17% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-48 356ns ± 0% 159ns ± 1% -55.28% (p=0.000 n=4+5)
IndexAnyUTF8/16:4-48 372ns ± 0% 158ns ± 0% -57.47% (p=0.008 n=5+5)
IndexAnyUTF8/16:8-48 712ns ± 0% 159ns ± 1% -77.70% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-48 829ns ± 0% 129ns ± 0% -84.44% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-48 1.55µs ± 0% 0.16µs ± 0% -89.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-48 2.77µs ± 0% 0.14µs ± 0% -94.94% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.85µs ± 0% 1.63µs ± 1% -42.74% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 5.14µs ± 1% 2.03µs ± 0% -60.51% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-48 5.56µs ± 0% 2.03µs ± 0% -63.52% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.0µs ± 0% -81.22% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 12.9µs ± 0% 1.9µs ± 0% -85.55% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-48 24.2µs ± 0% 2.1µs ± 0% -91.29% (p=0.016 n=5+4)
IndexAnyUTF8/256:64-48 43.7µs ± 0% 2.0µs ± 0% -95.32% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-48 13.7ns ± 1% 12.8ns ± 0% -6.57% (p=0.016 n=5+4)
LastIndexAnyASCII/1:2-48 14.7ns ± 0% 12.7ns ± 1% -13.33% (p=0.000 n=4+5)
LastIndexAnyASCII/1:4-48 16.9ns ± 0% 12.7ns ± 1% -24.73% (p=0.000 n=4+5)
LastIndexAnyASCII/1:8-48 20.5ns ± 0% 12.7ns ± 0% -37.85% (p=0.000 n=4+5)
LastIndexAnyASCII/1:16-48 28.0ns ± 0% 11.7ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:32-48 69.8ns ± 0% 12.4ns ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 73.8ns ± 0% 13.3ns ± 0% -82.03% (p=0.000 n=4+5)
LastIndexAnyASCII/16:1-48 35.5ns ± 0% 35.5ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 36.0ns ± 0% 36.1ns ± 0% +0.28% (p=0.016 n=4+5)
LastIndexAnyASCII/16:4-48 40.3ns ± 2% 40.0ns ± 6% ~ (p=0.651 n=5+5)
LastIndexAnyASCII/16:8-48 50.3ns ± 0% 50.2ns ± 9% ~ (p=0.175 n=4+5)
LastIndexAnyASCII/16:16-48 62.4ns ± 4% 64.4ns ± 0% +3.28% (p=0.016 n=5+4)
LastIndexAnyASCII/16:32-48 98.9ns ± 0% 98.4ns ± 0% -0.53% (p=0.016 n=5+4)
LastIndexAnyASCII/16:64-48 160ns ± 1% 161ns ± 1% ~ (p=0.325 n=5+5)
LastIndexAnyASCII/256:1-48 300ns ± 0% 301ns ± 0% +0.33% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 304ns ± 0% 304ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.556 n=4+5)
LastIndexAnyASCII/256:8-48 320ns ± 0% 321ns ± 0% ~ (p=0.143 n=5+5)
LastIndexAnyASCII/256:16-48 333ns ± 0% 335ns ± 0% +0.60% (p=0.029 n=4+4)
LastIndexAnyASCII/256:32-48 367ns ± 0% 366ns ± 0% ~ (p=0.095 n=4+5)
LastIndexAnyASCII/256:64-48 431ns ± 0% 424ns ± 0% -1.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-48 19.7ns ± 1% 11.9ns ± 0% -39.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 27.6ns ± 1% 11.9ns ± 0% -56.82% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 29.9ns ± 0% 11.9ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/1:8-48 48.7ns ± 0% 11.9ns ± 0% -75.54% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 57.8ns ± 0% 11.4ns ± 0% -80.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:32-48 94.7ns ± 0% 12.2ns ± 0% -87.07% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 163ns ± 0% 13ns ± 1% -91.93% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 258ns ± 0% 88ns ± 0% -65.76% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-48 400ns ± 0% 162ns ± 0% -59.38% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 415ns ± 0% 162ns ± 0% -60.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-48 737ns ± 0% 162ns ± 0% -78.02% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:16-48 882ns ± 0% 128ns ± 0% -85.49% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-48 1.47µs ± 0% 0.16µs ± 0% -89.29% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:64-48 2.56µs ± 0% 0.14µs ± 0% -94.41% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:1-48 3.60µs ± 0% 1.23µs ± 0% -65.67% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.78µs ± 0% 2.18µs ± 0% -62.32% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-48 6.26µs ± 0% 2.18µs ± 0% -65.15% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.2µs ± 0% 2.2µs ± 0% -80.53% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 13.5µs ± 0% 1.9µs ± 0% -86.02% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:32-48 23.0µs ± 0% 2.1µs ± 0% -90.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-48 40.5µs ± 0% 2.1µs ± 0% -94.73% (p=0.008 n=5+5)
Change-Id: Ie05e306f8b184b989701868cb161ce8b3f18203b
Reviewed-on: https://go-review.googlesource.com/c/go/+/156998
Run-TryBot: eric fang <eric.fang@arm.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-12-23 02:15:44 +00:00
|
|
|
|
x := Repeat([]byte{'#'}, 2048) // Never matches set
|
|
|
|
|
|
cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
|
|
|
|
|
|
for k := 1; k <= 2048; k <<= 4 {
|
|
|
|
|
|
for j := 1; j <= 64; j <<= 1 {
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
IndexAny(x[:k], cs[:j])
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkIndexAnyUTF8(b *testing.B) {
|
|
|
|
|
|
x := Repeat([]byte{'#'}, 2048) // Never matches set
|
|
|
|
|
|
cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world."
|
|
|
|
|
|
for k := 1; k <= 2048; k <<= 4 {
|
|
|
|
|
|
for j := 1; j <= 64; j <<= 1 {
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
IndexAny(x[:k], cs[:j])
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
strings, bytes: improve IndexAny and LastIndexAny performance
For the case of a pattern containing multi-byte rune, the time complexity of the
previous algorithm is O(nm), and if both input arguments are long, the search
performance will be poor. This CL improves the searching performance for these
cases by using IndexRune, which is mainly implemented with IndexByte and Index.
As IndexByte and Index are specially optimized with some powerful instructions
for short patterns (an UTF8 rune is 1 to 4 bytes), so they can help to reduce the
runtime complexity of IndexAny and LastIndexAny.
Another optimization method is using hash table, however, the actual test results
show that using indexrune is better, and the space complexity is lower.
There are two fast paths in IndexAny and LastIndexAny for cases where the length
of the input arguements are 1, and their locations are not exactly the same, which
is determined based on the actual test results.
Benchmarks on arm64 and amd64:
name old time/op new time/op delta
pkg:strings goos:linux goarch:arm64
IndexAnyASCII/1:1-8 23.7ns ± 3% 28.5ns ± 0% +20.15% (p=0.008 n=5+5)
IndexAnyASCII/1:2-8 18.0ns ± 0% 33.1ns ± 0% +83.67% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 20.0ns ± 0% 36.0ns ± 0% +80.00% (p=0.029 n=4+4)
IndexAnyASCII/1:8-8 36.1ns ± 0% 36.0ns ± 0% ~ (p=0.095 n=5+4)
IndexAnyASCII/1:16-8 48.1ns ± 0% 36.0ns ± 0% -25.19% (p=0.029 n=4+4)
IndexAnyASCII/1:32-8 72.1ns ± 0% 36.0ns ± 0% -50.01% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 120ns ± 0% 39ns ± 0% -67.83% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.0ns ± 0% 28.5ns ± 0% -60.95% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 76.8ns ± 0% 77.0ns ± 0% ~ (p=1.000 n=5+5)
IndexAnyASCII/16:4-8 83.2ns ± 1% 83.0ns ± 0% ~ (p=0.770 n=5+5)
IndexAnyASCII/16:8-8 111ns ± 1% 107ns ± 0% -3.25% (p=0.008 n=5+5)
IndexAnyASCII/16:16-8 139ns ± 1% 137ns ± 0% -1.58% (p=0.008 n=5+5)
IndexAnyASCII/16:32-8 199ns ± 1% 197ns ± 0% -1.20% (p=0.008 n=5+5)
IndexAnyASCII/16:64-8 307ns ± 0% 313ns ± 0% +1.82% (p=0.016 n=5+4)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 0% -90.31% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 678ns ± 0% 683ns ± 0% +0.68% (p=0.008 n=5+5)
IndexAnyASCII/256:4-8 685ns ± 0% 683ns ± 0% -0.29% (p=0.000 n=5+4)
IndexAnyASCII/256:8-8 711ns ± 0% 708ns ± 0% -0.48% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 740ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:32-8 799ns ± 0% 798ns ± 0% -0.18% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 910ns ± 0% 914ns ± 0% +0.44% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.1ns ± 0% 19.0ns ± 0% -29.79% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.1ns ± 0% 33.0ns ± 0% -25.17% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 46.1ns ± 0% 33.1ns ± 0% -28.29% (p=0.016 n=4+5)
IndexAnyUTF8/1:8-8 85.1ns ± 0% 33.0ns ± 0% -61.18% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 36ns ± 0% -67.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:32-8 188ns ± 0% 36ns ± 0% -80.85% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 332ns ± 0% 39ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/16:1-8 293ns ± 0% 54ns ± 0% -81.56% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 349ns ± 0% -37.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 546ns ± 1% 349ns ± 0% -36.10% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.22µs ± 0% 0.35µs ± 0% -71.39% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.63µs ± 1% 0.42µs ± 0% -73.98% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.87µs ± 0% 0.42µs ± 0% -85.22% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.47µs ± 0% -90.98% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.26µs ± 0% 0.47µs ± 0% -88.85% (p=0.000 n=4+5)
IndexAnyUTF8/256:2-8 8.62µs ± 0% 5.15µs ± 0% -40.21% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-8 8.25µs ± 0% 5.15µs ± 0% -37.50% (p=0.016 n=5+4)
IndexAnyUTF8/256:8-8 19.2µs ± 1% 5.2µs ± 0% -73.08% (p=0.016 n=5+4)
IndexAnyUTF8/256:16-8 25.6µs ± 1% 6.3µs ± 0% -75.32% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.6µs ± 0% 6.3µs ± 0% -86.15% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-8 82.4µs ± 0% 7.0µs ± 0% -91.53% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 33.5ns ± 0% +45.65% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 33.5ns ± 0% +36.73% (p=0.016 n=4+5)
LastIndexAnyASCII/1:4-8 27.5ns ± 0% 35.5ns ± 0% +29.09% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-8 44.5ns ± 0% 35.5ns ± 0% -20.13% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-8 56.5ns ± 0% 35.5ns ± 0% -37.15% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 80.3ns ± 0% 35.5ns ± 0% -55.79% (p=0.000 n=5+4)
LastIndexAnyASCII/1:64-8 129ns ± 0% 40ns ± 0% -68.85% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.8ns ± 0% 72.7ns ± 0% -0.19% (p=0.016 n=4+5)
LastIndexAnyASCII/16:2-8 75.4ns ± 0% 75.1ns ± 0% ~ (p=0.127 n=5+5)
LastIndexAnyASCII/16:4-8 81.9ns ± 1% 80.2ns ± 0% -2.00% (p=0.008 n=5+5)
LastIndexAnyASCII/16:8-8 110ns ± 1% 108ns ± 0% -1.46% (p=0.008 n=5+5)
LastIndexAnyASCII/16:16-8 138ns ± 1% 134ns ± 0% -3.18% (p=0.008 n=5+5)
LastIndexAnyASCII/16:32-8 198ns ± 0% 197ns ± 0% -0.51% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 313ns ± 0% +1.30% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-8 652ns ± 0% 653ns ± 0% +0.21% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 656ns ± 0% 656ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:4-8 663ns ± 0% 663ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/256:8-8 691ns ± 0% 690ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/256:16-8 719ns ± 0% 715ns ± 0% -0.53% (p=0.000 n=5+4)
LastIndexAnyASCII/256:32-8 779ns ± 0% 780ns ± 0% +0.13% (p=0.029 n=4+4)
LastIndexAnyASCII/256:64-8 890ns ± 0% 894ns ± 0% +0.45% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-8 31.6ns ± 0% 33.5ns ± 0% +6.01% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 33.5ns ± 0% -30.99% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-8 48.6ns ± 0% 33.5ns ± 0% -31.13% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:8-8 89.6ns ± 0% 33.5ns ± 0% -62.56% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 113ns ± 1% 36ns ± 0% -68.47% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 190ns ± 0% 36ns ± 0% -81.26% (p=0.029 n=4+4)
LastIndexAnyUTF8/1:64-8 327ns ± 0% 40ns ± 0% -87.77% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-8 364ns ± 0% 158ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/16:2-8 636ns ± 0% 472ns ± 0% -25.79% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:4-8 630ns ± 0% 472ns ± 0% -25.03% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.28µs ± 0% 0.47µs ± 0% -63.09% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.53µs ± 0% -68.39% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-8 2.88µs ± 0% 0.53µs ± 0% -81.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-8 5.08µs ± 0% 0.57µs ± 0% -88.79% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.41µs ± 0% 2.03µs ± 0% -62.46% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:2-8 9.77µs ± 0% 7.14µs ± 0% -26.97% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.63µs ± 0% 7.14µs ± 0% -25.86% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.0µs ± 0% 7.1µs ± 0% -64.30% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.1µs ± 1% 8.0µs ± 0% -69.40% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 45.6µs ± 1% 8.0µs ± 0% -82.51% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 80.8µs ± 0% 8.6µs ± 0% -89.33% (p=0.016 n=5+4)
pkg:bytes goos:linux goarch:arm64
IndexAnyASCII/1:1-8 26.2ns ± 1% 26.5ns ± 0% +1.30% (p=0.016 n=5+4)
IndexAnyASCII/1:2-8 18.5ns ± 0% 26.5ns ± 0% +43.24% (p=0.008 n=5+5)
IndexAnyASCII/1:4-8 21.0ns ± 0% 26.5ns ± 0% +26.38% (p=0.008 n=5+5)
IndexAnyASCII/1:8-8 37.5ns ± 0% 26.5ns ± 0% -29.33% (p=0.000 n=5+4)
IndexAnyASCII/1:16-8 49.6ns ± 0% 26.5ns ± 0% -46.49% (p=0.008 n=5+5)
IndexAnyASCII/1:32-8 73.6ns ± 0% 30.1ns ± 0% -59.16% (p=0.008 n=5+5)
IndexAnyASCII/1:64-8 122ns ± 0% 33ns ± 0% -73.23% (p=0.008 n=5+5)
IndexAnyASCII/16:1-8 73.7ns ± 0% 33.4ns ± 0% -54.71% (p=0.008 n=5+5)
IndexAnyASCII/16:2-8 79.1ns ± 0% 78.9ns ± 0% -0.30% (p=0.016 n=4+5)
IndexAnyASCII/16:4-8 84.8ns ± 0% 86.1ns ± 0% +1.58% (p=0.016 n=5+4)
IndexAnyASCII/16:8-8 111ns ± 0% 111ns ± 0% ~ (all equal)
IndexAnyASCII/16:16-8 139ns ± 0% 144ns ± 0% +3.60% (p=0.016 n=4+5)
IndexAnyASCII/16:32-8 196ns ± 0% 207ns ± 0% +5.61% (p=0.016 n=5+4)
IndexAnyASCII/16:64-8 311ns ± 0% 320ns ± 0% +2.89% (p=0.016 n=4+5)
IndexAnyASCII/256:1-8 674ns ± 0% 65ns ± 1% -90.35% (p=0.008 n=5+5)
IndexAnyASCII/256:2-8 680ns ± 0% 680ns ± 0% ~ (p=0.444 n=5+5)
IndexAnyASCII/256:4-8 686ns ± 0% 687ns ± 0% ~ (p=0.167 n=5+5)
IndexAnyASCII/256:8-8 713ns ± 0% 712ns ± 0% -0.14% (p=0.008 n=5+5)
IndexAnyASCII/256:16-8 740ns ± 0% 744ns ± 0% +0.54% (p=0.016 n=5+4)
IndexAnyASCII/256:32-8 797ns ± 0% 808ns ± 0% +1.43% (p=0.008 n=5+5)
IndexAnyASCII/256:64-8 912ns ± 0% 921ns ± 0% +0.99% (p=0.016 n=4+5)
IndexAnyUTF8/1:1-8 27.5ns ± 0% 26.5ns ± 0% -3.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-8 44.5ns ± 0% 26.5ns ± 0% -40.50% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-8 45.6ns ± 0% 26.5ns ± 0% -41.89% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-8 85.8ns ± 1% 26.5ns ± 0% -69.11% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-8 110ns ± 1% 26ns ± 0% -76.00% (p=0.016 n=5+4)
IndexAnyUTF8/1:32-8 188ns ± 0% 30ns ± 0% -84.04% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-8 333ns ± 0% 33ns ± 0% -90.20% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-8 294ns ± 0% 235ns ± 0% -20.07% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-8 563ns ± 0% 309ns ± 0% -45.12% (p=0.008 n=5+5)
IndexAnyUTF8/16:4-8 558ns ± 1% 309ns ± 0% -44.60% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-8 1.23µs ± 0% 0.31µs ± 0% -74.79% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-8 1.62µs ± 2% 0.31µs ± 0% -80.93% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-8 2.86µs ± 0% 0.38µs ± 0% -86.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-8 5.18µs ± 0% 0.42µs ± 0% -91.86% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-8 4.27µs ± 1% 3.30µs ± 1% -22.75% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-8 8.61µs ± 0% 4.45µs ± 0% -48.31% (p=0.016 n=4+5)
IndexAnyUTF8/256:4-8 8.44µs ± 0% 4.45µs ± 0% -47.23% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-8 19.2µs ± 0% 4.5µs ± 0% -76.78% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-8 25.6µs ± 0% 4.5µs ± 0% -82.63% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-8 45.4µs ± 0% 5.5µs ± 0% -87.85% (p=0.016 n=4+5)
IndexAnyUTF8/256:64-8 82.5µs ± 0% 6.2µs ± 0% -92.49% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-8 23.0ns ± 0% 26.5ns ± 0% +15.02% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-8 24.5ns ± 0% 26.5ns ± 0% +8.16% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-8 27.8ns ± 0% 26.5ns ± 0% -4.68% (p=0.029 n=4+4)
LastIndexAnyASCII/1:8-8 45.1ns ± 1% 26.5ns ± 0% -41.29% (p=0.000 n=5+4)
LastIndexAnyASCII/1:16-8 57.1ns ± 0% 26.5ns ± 0% -53.61% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-8 81.5ns ± 0% 30.0ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:64-8 129ns ± 0% 32ns ± 0% -74.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-8 72.6ns ± 0% 72.1ns ± 0% -0.63% (p=0.000 n=4+5)
LastIndexAnyASCII/16:2-8 77.2ns ± 0% 77.2ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:4-8 83.1ns ± 0% 83.2ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyASCII/16:8-8 109ns ± 1% 108ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/16:16-8 136ns ± 0% 136ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:32-8 195ns ± 0% 197ns ± 0% +0.82% (p=0.008 n=5+5)
LastIndexAnyASCII/16:64-8 309ns ± 0% 309ns ± 0% ~ (all equal)
LastIndexAnyASCII/256:1-8 653ns ± 0% 657ns ± 0% +0.61% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-8 659ns ± 0% 658ns ± 0% ~ (p=0.167 n=5+5)
LastIndexAnyASCII/256:4-8 664ns ± 0% 663ns ± 0% ~ (p=0.095 n=5+4)
LastIndexAnyASCII/256:8-8 698ns ± 0% 689ns ± 0% -1.29% (p=0.008 n=5+5)
LastIndexAnyASCII/256:16-8 726ns ± 0% 717ns ± 0% -1.24% (p=0.008 n=5+5)
LastIndexAnyASCII/256:32-8 777ns ± 0% 779ns ± 0% ~ (p=0.079 n=5+4)
LastIndexAnyASCII/256:64-8 889ns ± 0% 890ns ± 0% ~ (p=0.444 n=5+5)
LastIndexAnyUTF8/1:1-8 32.1ns ± 0% 26.5ns ± 0% -17.45% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:2-8 48.6ns ± 0% 26.5ns ± 0% -45.52% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:4-8 49.6ns ± 0% 26.5ns ± 0% -46.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-8 91.9ns ± 0% 26.5ns ± 0% -71.18% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-8 114ns ± 1% 26ns ± 0% -76.84% (p=0.000 n=5+4)
LastIndexAnyUTF8/1:32-8 203ns ± 6% 30ns ± 0% -85.25% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-8 330ns ± 0% 33ns ± 0% -90.14% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:1-8 365ns ± 0% 164ns ± 0% -55.04% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-8 638ns ± 0% 296ns ± 0% -53.58% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-8 634ns ± 0% 296ns ± 0% -53.31% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-8 1.30µs ± 0% 0.30µs ± 0% -77.18% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:16-8 1.66µs ± 0% 0.30µs ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-8 2.90µs ± 0% 0.38µs ± 0% -87.00% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:64-8 5.10µs ± 0% 0.42µs ± 0% -91.78% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:1-8 5.42µs ± 0% 2.12µs ± 0% -60.92% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-8 9.79µs ± 0% 4.26µs ± 0% -56.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-8 9.66µs ± 0% 4.26µs ± 0% -55.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-8 20.4µs ± 0% 4.3µs ± 0% -79.10% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-8 26.0µs ± 1% 4.3µs ± 0% -83.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-8 46.0µs ± 0% 5.5µs ± 0% -88.09% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-8 81.1µs ± 0% 6.2µs ± 0% -92.38% (p=0.008 n=5+5)
name old time/op new time/op delta
pkg:strings goos:linux goarch:amd64
IndexAnyASCII/1:1-48 10.0ns ± 0% 13.3ns ± 0% +33.00% (p=0.008 n=5+5)
IndexAnyASCII/1:2-48 11.0ns ± 0% 15.5ns ± 0% +40.55% (p=0.016 n=4+5)
IndexAnyASCII/1:4-48 12.9ns ± 0% 15.4ns ± 0% +19.69% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 18.6ns ± 0% 15.5ns ± 0% -16.45% (p=0.000 n=4+5)
IndexAnyASCII/1:16-48 30.1ns ± 0% 16.9ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/1:32-48 53.1ns ± 0% 18.6ns ± 0% -64.95% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 98.9ns ± 0% 17.4ns ± 0% -82.41% (p=0.000 n=5+4)
IndexAnyASCII/16:1-48 35.0ns ± 0% 14.2ns ± 0% -59.47% (p=0.000 n=5+4)
IndexAnyASCII/16:2-48 35.5ns ± 0% 35.6ns ± 0% ~ (p=0.238 n=5+4)
IndexAnyASCII/16:4-48 40.8ns ± 0% 40.7ns ± 1% ~ (p=0.643 n=5+5)
IndexAnyASCII/16:8-48 50.8ns ± 0% 50.9ns ± 1% ~ (p=1.000 n=4+5)
IndexAnyASCII/16:16-48 64.0ns ± 1% 64.5ns ± 1% ~ (p=0.071 n=5+5)
IndexAnyASCII/16:32-48 98.3ns ± 0% 100.8ns ± 1% +2.52% (p=0.008 n=5+5)
IndexAnyASCII/16:64-48 156ns ± 0% 157ns ± 0% ~ (p=0.238 n=4+5)
IndexAnyASCII/256:1-48 299ns ± 0% 24ns ± 3% -92.12% (p=0.008 n=5+5)
IndexAnyASCII/256:2-48 303ns ± 0% 304ns ± 0% ~ (p=0.762 n=5+5)
IndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.476 n=5+5)
IndexAnyASCII/256:8-48 321ns ± 0% 321ns ± 0% ~ (p=0.429 n=4+5)
IndexAnyASCII/256:16-48 334ns ± 0% 335ns ± 0% ~ (p=0.079 n=5+4)
IndexAnyASCII/256:32-48 367ns ± 0% 365ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyASCII/256:64-48 431ns ± 1% 421ns ± 0% -2.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.2ns ± 0% 10.8ns ± 0% -37.21% (p=0.029 n=4+4)
IndexAnyUTF8/1:2-48 26.7ns ± 0% 15.6ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:4-48 28.2ns ± 0% 15.6ns ± 0% -44.68% (p=0.000 n=5+4)
IndexAnyUTF8/1:8-48 48.8ns ± 0% 15.6ns ± 0% -68.03% (p=0.029 n=4+4)
IndexAnyUTF8/1:16-48 58.3ns ± 0% 16.2ns ± 0% ~ (p=0.079 n=4+5)
IndexAnyUTF8/1:32-48 103ns ± 0% 18ns ± 0% -82.27% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 182ns ± 0% 17ns ± 0% -90.53% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 197ns ± 0% 25ns ± 0% -87.34% (p=0.000 n=5+4)
IndexAnyUTF8/16:2-48 348ns ± 0% 163ns ± 0% -53.11% (p=0.000 n=5+4)
IndexAnyUTF8/16:4-48 374ns ± 0% 163ns ± 0% -56.37% (p=0.000 n=5+4)
IndexAnyUTF8/16:8-48 716ns ± 0% 163ns ± 0% -77.22% (p=0.000 n=5+4)
IndexAnyUTF8/16:16-48 859ns ± 0% 175ns ± 0% -79.63% (p=0.000 n=5+4)
IndexAnyUTF8/16:32-48 1.58µs ± 0% 0.20µs ± 0% -87.01% (p=0.029 n=4+4)
IndexAnyUTF8/16:64-48 2.84µs ± 0% 0.19µs ± 1% -93.34% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.61µs ± 0% 0.27µs ± 0% -89.81% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 4.95µs ± 0% 2.23µs ± 0% -54.91% (p=0.016 n=5+4)
IndexAnyUTF8/256:4-48 5.55µs ± 0% 2.23µs ± 0% -59.72% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.2µs ± 0% -79.39% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 13.1µs ± 0% 2.5µs ± 0% -81.21% (p=0.016 n=4+5)
IndexAnyUTF8/256:32-48 24.7µs ± 0% 2.8µs ± 0% -88.49% (p=0.008 n=5+5)
IndexAnyUTF8/256:64-48 45.0µs ± 0% 2.6µs ± 1% -94.23% (p=0.008 n=5+5)
LastIndexAnyASCII/1:1-48 13.9ns ± 0% 15.2ns ± 0% +9.35% (p=0.008 n=5+5)
LastIndexAnyASCII/1:2-48 14.4ns ± 0% 15.2ns ± 0% +5.56% (p=0.008 n=5+5)
LastIndexAnyASCII/1:4-48 16.7ns ± 0% 15.2ns ± 0% -8.98% (p=0.008 n=5+5)
LastIndexAnyASCII/1:8-48 24.0ns ± 0% 15.2ns ± 0% -36.67% (p=0.008 n=5+5)
LastIndexAnyASCII/1:16-48 35.6ns ± 0% 15.0ns ± 0% -57.82% (p=0.008 n=5+5)
LastIndexAnyASCII/1:32-48 68.9ns ± 0% 16.7ns ± 0% -75.75% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 104ns ± 0% 17ns ± 1% -83.81% (p=0.008 n=5+5)
LastIndexAnyASCII/16:1-48 35.0ns ± 0% 35.0ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 35.6ns ± 0% 35.6ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:4-48 41.0ns ± 0% 40.8ns ± 0% -0.49% (p=0.032 n=5+5)
LastIndexAnyASCII/16:8-48 50.9ns ± 0% 50.7ns ± 1% ~ (p=0.397 n=5+5)
LastIndexAnyASCII/16:16-48 64.3ns ± 1% 64.4ns ± 1% ~ (p=1.000 n=4+5)
LastIndexAnyASCII/16:32-48 100ns ± 0% 100ns ± 0% +0.38% (p=0.016 n=4+5)
LastIndexAnyASCII/16:64-48 157ns ± 1% 163ns ± 0% +3.82% (p=0.008 n=5+5)
LastIndexAnyASCII/256:1-48 302ns ± 0% 300ns ± 0% -0.53% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 305ns ± 0% 303ns ± 0% -0.66% (p=0.000 n=5+4)
LastIndexAnyASCII/256:4-48 313ns ± 0% 307ns ± 0% -2.04% (p=0.000 n=4+5)
LastIndexAnyASCII/256:8-48 323ns ± 0% 315ns ± 0% -2.48% (p=0.029 n=4+4)
LastIndexAnyASCII/256:16-48 333ns ± 0% 332ns ± 0% -0.30% (p=0.048 n=5+5)
LastIndexAnyASCII/256:32-48 366ns ± 0% 367ns ± 0% ~ (p=0.238 n=4+5)
LastIndexAnyASCII/256:64-48 430ns ± 0% 430ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyUTF8/1:1-48 21.1ns ± 0% 13.9ns ± 0% -34.00% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 29.5ns ± 0% 13.9ns ± 0% -52.95% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 31.6ns ± 0% 13.9ns ± 0% -55.96% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:8-48 51.1ns ± 0% 13.9ns ± 0% -72.81% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 58.9ns ± 0% 14.6ns ± 0% -75.23% (p=0.016 n=5+4)
LastIndexAnyUTF8/1:32-48 103ns ± 0% 16ns ± 1% -84.12% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 177ns ± 0% 17ns ± 1% -90.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 275ns ± 1% 105ns ± 0% -61.85% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:2-48 406ns ± 0% 216ns ± 0% -46.70% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 458ns ± 0% 216ns ± 0% -52.75% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:8-48 753ns ± 0% 216ns ± 0% -71.31% (p=0.029 n=4+4)
LastIndexAnyUTF8/16:16-48 902ns ± 0% 221ns ± 0% -75.50% (p=0.016 n=5+4)
LastIndexAnyUTF8/16:32-48 1.57µs ± 0% 0.24µs ± 0% -84.46% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:64-48 2.77µs ± 0% 0.24µs ± 0% -91.22% (p=0.000 n=5+4)
LastIndexAnyUTF8/256:1-48 4.06µs ± 0% 1.53µs ± 0% -62.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.92µs ± 0% 3.04µs ± 0% -48.55% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:4-48 6.82µs ± 0% 3.04µs ± 0% -55.34% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.5µs ± 0% 3.0µs ± 0% -73.48% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 14.1µs ± 0% 3.1µs ± 0% -77.85% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:32-48 24.5µs ± 0% 3.5µs ± 0% -85.85% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:64-48 44.0µs ± 0% 3.5µs ± 0% -92.12% (p=0.008 n=5+5)
pkg:bytes goos:linux goarch:amd64
IndexAnyASCII/1:1-48 9.56ns ± 0% 11.00ns ± 0% +15.06% (p=0.016 n=5+4)
IndexAnyASCII/1:2-48 11.0ns ± 0% 10.8ns ± 2% -1.64% (p=0.048 n=5+5)
IndexAnyASCII/1:4-48 13.9ns ± 0% 11.0ns ± 1% -21.15% (p=0.008 n=5+5)
IndexAnyASCII/1:8-48 19.6ns ± 0% 10.8ns ± 3% -44.90% (p=0.008 n=5+5)
IndexAnyASCII/1:16-48 31.1ns ± 0% 11.5ns ± 0% -63.02% (p=0.008 n=5+5)
IndexAnyASCII/1:32-48 54.0ns ± 0% 11.8ns ± 0% -78.15% (p=0.000 n=5+4)
IndexAnyASCII/1:64-48 100ns ± 0% 13ns ± 0% -86.89% (p=0.008 n=5+5)
IndexAnyASCII/16:1-48 35.5ns ± 0% 14.8ns ± 0% -58.26% (p=0.008 n=5+5)
IndexAnyASCII/16:2-48 36.2ns ± 1% 36.0ns ± 1% ~ (p=0.087 n=5+5)
IndexAnyASCII/16:4-48 40.3ns ± 1% 39.7ns ± 4% ~ (p=0.175 n=4+5)
IndexAnyASCII/16:8-48 48.7ns ± 5% 45.8ns ± 0% -6.02% (p=0.016 n=5+4)
IndexAnyASCII/16:16-48 64.1ns ±11% 62.1ns ± 1% ~ (p=0.143 n=5+5)
IndexAnyASCII/16:32-48 97.9ns ± 1% 98.3ns ± 1% ~ (p=0.294 n=5+5)
IndexAnyASCII/16:64-48 163ns ± 0% 157ns ± 0% -3.68% (p=0.008 n=5+5)
IndexAnyASCII/256:1-48 389ns ± 0% 25ns ± 0% -93.65% (p=0.000 n=5+4)
IndexAnyASCII/256:2-48 391ns ± 0% 307ns ± 0% -21.48% (p=0.000 n=5+4)
IndexAnyASCII/256:4-48 394ns ± 0% 323ns ± 0% -17.92% (p=0.008 n=5+5)
IndexAnyASCII/256:8-48 402ns ± 0% 323ns ± 0% -19.51% (p=0.008 n=5+5)
IndexAnyASCII/256:16-48 414ns ± 0% 334ns ± 0% -19.32% (p=0.016 n=4+5)
IndexAnyASCII/256:32-48 446ns ± 0% 367ns ± 0% -17.75% (p=0.016 n=5+4)
IndexAnyASCII/256:64-48 511ns ± 0% 424ns ± 0% -17.02% (p=0.008 n=5+5)
IndexAnyUTF8/1:1-48 17.4ns ± 0% 11.0ns ± 0% -36.64% (p=0.008 n=5+5)
IndexAnyUTF8/1:2-48 27.3ns ± 1% 11.0ns ± 0% -59.74% (p=0.008 n=5+5)
IndexAnyUTF8/1:4-48 28.7ns ± 0% 11.0ns ± 0% -61.73% (p=0.008 n=5+5)
IndexAnyUTF8/1:8-48 49.2ns ± 0% 11.0ns ± 0% -77.66% (p=0.008 n=5+5)
IndexAnyUTF8/1:16-48 56.0ns ± 0% 11.5ns ± 0% -79.46% (p=0.000 n=5+4)
IndexAnyUTF8/1:32-48 102ns ± 0% 12ns ± 0% -88.24% (p=0.008 n=5+5)
IndexAnyUTF8/1:64-48 177ns ± 0% 13ns ± 0% -92.51% (p=0.008 n=5+5)
IndexAnyUTF8/16:1-48 212ns ± 0% 112ns ± 0% -47.17% (p=0.008 n=5+5)
IndexAnyUTF8/16:2-48 356ns ± 0% 159ns ± 1% -55.28% (p=0.000 n=4+5)
IndexAnyUTF8/16:4-48 372ns ± 0% 158ns ± 0% -57.47% (p=0.008 n=5+5)
IndexAnyUTF8/16:8-48 712ns ± 0% 159ns ± 1% -77.70% (p=0.008 n=5+5)
IndexAnyUTF8/16:16-48 829ns ± 0% 129ns ± 0% -84.44% (p=0.008 n=5+5)
IndexAnyUTF8/16:32-48 1.55µs ± 0% 0.16µs ± 0% -89.87% (p=0.008 n=5+5)
IndexAnyUTF8/16:64-48 2.77µs ± 0% 0.14µs ± 0% -94.94% (p=0.008 n=5+5)
IndexAnyUTF8/256:1-48 2.85µs ± 0% 1.63µs ± 1% -42.74% (p=0.008 n=5+5)
IndexAnyUTF8/256:2-48 5.14µs ± 1% 2.03µs ± 0% -60.51% (p=0.008 n=5+5)
IndexAnyUTF8/256:4-48 5.56µs ± 0% 2.03µs ± 0% -63.52% (p=0.008 n=5+5)
IndexAnyUTF8/256:8-48 10.8µs ± 0% 2.0µs ± 0% -81.22% (p=0.008 n=5+5)
IndexAnyUTF8/256:16-48 12.9µs ± 0% 1.9µs ± 0% -85.55% (p=0.008 n=5+5)
IndexAnyUTF8/256:32-48 24.2µs ± 0% 2.1µs ± 0% -91.29% (p=0.016 n=5+4)
IndexAnyUTF8/256:64-48 43.7µs ± 0% 2.0µs ± 0% -95.32% (p=0.016 n=5+4)
LastIndexAnyASCII/1:1-48 13.7ns ± 1% 12.8ns ± 0% -6.57% (p=0.016 n=5+4)
LastIndexAnyASCII/1:2-48 14.7ns ± 0% 12.7ns ± 1% -13.33% (p=0.000 n=4+5)
LastIndexAnyASCII/1:4-48 16.9ns ± 0% 12.7ns ± 1% -24.73% (p=0.000 n=4+5)
LastIndexAnyASCII/1:8-48 20.5ns ± 0% 12.7ns ± 0% -37.85% (p=0.000 n=4+5)
LastIndexAnyASCII/1:16-48 28.0ns ± 0% 11.7ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyASCII/1:32-48 69.8ns ± 0% 12.4ns ± 0% -82.19% (p=0.008 n=5+5)
LastIndexAnyASCII/1:64-48 73.8ns ± 0% 13.3ns ± 0% -82.03% (p=0.000 n=4+5)
LastIndexAnyASCII/16:1-48 35.5ns ± 0% 35.5ns ± 0% ~ (all equal)
LastIndexAnyASCII/16:2-48 36.0ns ± 0% 36.1ns ± 0% +0.28% (p=0.016 n=4+5)
LastIndexAnyASCII/16:4-48 40.3ns ± 2% 40.0ns ± 6% ~ (p=0.651 n=5+5)
LastIndexAnyASCII/16:8-48 50.3ns ± 0% 50.2ns ± 9% ~ (p=0.175 n=4+5)
LastIndexAnyASCII/16:16-48 62.4ns ± 4% 64.4ns ± 0% +3.28% (p=0.016 n=5+4)
LastIndexAnyASCII/16:32-48 98.9ns ± 0% 98.4ns ± 0% -0.53% (p=0.016 n=5+4)
LastIndexAnyASCII/16:64-48 160ns ± 1% 161ns ± 1% ~ (p=0.325 n=5+5)
LastIndexAnyASCII/256:1-48 300ns ± 0% 301ns ± 0% +0.33% (p=0.008 n=5+5)
LastIndexAnyASCII/256:2-48 304ns ± 0% 304ns ± 0% ~ (p=1.000 n=5+5)
LastIndexAnyASCII/256:4-48 311ns ± 0% 311ns ± 0% ~ (p=0.556 n=4+5)
LastIndexAnyASCII/256:8-48 320ns ± 0% 321ns ± 0% ~ (p=0.143 n=5+5)
LastIndexAnyASCII/256:16-48 333ns ± 0% 335ns ± 0% +0.60% (p=0.029 n=4+4)
LastIndexAnyASCII/256:32-48 367ns ± 0% 366ns ± 0% ~ (p=0.095 n=4+5)
LastIndexAnyASCII/256:64-48 431ns ± 0% 424ns ± 0% -1.62% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:1-48 19.7ns ± 1% 11.9ns ± 0% -39.47% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:2-48 27.6ns ± 1% 11.9ns ± 0% -56.82% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:4-48 29.9ns ± 0% 11.9ns ± 0% ~ (p=0.079 n=4+5)
LastIndexAnyUTF8/1:8-48 48.7ns ± 0% 11.9ns ± 0% -75.54% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:16-48 57.8ns ± 0% 11.4ns ± 0% -80.26% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:32-48 94.7ns ± 0% 12.2ns ± 0% -87.07% (p=0.008 n=5+5)
LastIndexAnyUTF8/1:64-48 163ns ± 0% 13ns ± 1% -91.93% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:1-48 258ns ± 0% 88ns ± 0% -65.76% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:2-48 400ns ± 0% 162ns ± 0% -59.38% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:4-48 415ns ± 0% 162ns ± 0% -60.87% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:8-48 737ns ± 0% 162ns ± 0% -78.02% (p=0.000 n=5+4)
LastIndexAnyUTF8/16:16-48 882ns ± 0% 128ns ± 0% -85.49% (p=0.008 n=5+5)
LastIndexAnyUTF8/16:32-48 1.47µs ± 0% 0.16µs ± 0% -89.29% (p=0.000 n=4+5)
LastIndexAnyUTF8/16:64-48 2.56µs ± 0% 0.14µs ± 0% -94.41% (p=0.016 n=5+4)
LastIndexAnyUTF8/256:1-48 3.60µs ± 0% 1.23µs ± 0% -65.67% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:2-48 5.78µs ± 0% 2.18µs ± 0% -62.32% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:4-48 6.26µs ± 0% 2.18µs ± 0% -65.15% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:8-48 11.2µs ± 0% 2.2µs ± 0% -80.53% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:16-48 13.5µs ± 0% 1.9µs ± 0% -86.02% (p=0.016 n=4+5)
LastIndexAnyUTF8/256:32-48 23.0µs ± 0% 2.1µs ± 0% -90.72% (p=0.008 n=5+5)
LastIndexAnyUTF8/256:64-48 40.5µs ± 0% 2.1µs ± 0% -94.73% (p=0.008 n=5+5)
Change-Id: Ie05e306f8b184b989701868cb161ce8b3f18203b
Reviewed-on: https://go-review.googlesource.com/c/go/+/156998
Run-TryBot: eric fang <eric.fang@arm.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-12-23 02:15:44 +00:00
|
|
|
|
func BenchmarkLastIndexAnyASCII(b *testing.B) {
|
|
|
|
|
|
x := Repeat([]byte{'#'}, 2048) // Never matches set
|
|
|
|
|
|
cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
|
|
|
|
|
|
for k := 1; k <= 2048; k <<= 4 {
|
|
|
|
|
|
for j := 1; j <= 64; j <<= 1 {
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
LastIndexAny(x[:k], cs[:j])
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkLastIndexAnyUTF8(b *testing.B) {
|
|
|
|
|
|
x := Repeat([]byte{'#'}, 2048) // Never matches set
|
|
|
|
|
|
cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world."
|
|
|
|
|
|
for k := 1; k <= 2048; k <<= 4 {
|
|
|
|
|
|
for j := 1; j <= 64; j <<= 1 {
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
LastIndexAny(x[:k], cs[:j])
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight
An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.
Uses of ContainsAny|IndexAny|LastIndexAny:
6% are 1 character (e.g., "\n" or " ")
58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
24% are 5-9 characters (e.g., "()[]*^$")
10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.
Uses of Trim|TrimLeft|TrimRight:
71% are 1 character (e.g., "\n" or " ")
14% are 2 characters (e.g., "\r\n")
10% are 3-4 characters (e.g., " \t\r\n")
5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.
The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.
== bytes package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.09 5.23 +2.75%
BenchmarkIndexAnyASCII/1:2-4 5.81 5.85 +0.69%
BenchmarkIndexAnyASCII/1:4-4 7.22 7.50 +3.88%
BenchmarkIndexAnyASCII/1:8-4 11.0 11.1 +0.91%
BenchmarkIndexAnyASCII/1:16-4 17.5 17.8 +1.71%
BenchmarkIndexAnyASCII/16:1-4 36.0 34.0 -5.56%
BenchmarkIndexAnyASCII/16:2-4 46.6 36.5 -21.67%
BenchmarkIndexAnyASCII/16:4-4 78.0 40.4 -48.21%
BenchmarkIndexAnyASCII/16:8-4 136 47.4 -65.15%
BenchmarkIndexAnyASCII/16:16-4 254 61.5 -75.79%
BenchmarkIndexAnyASCII/256:1-4 542 388 -28.41%
BenchmarkIndexAnyASCII/256:2-4 705 382 -45.82%
BenchmarkIndexAnyASCII/256:4-4 1089 386 -64.55%
BenchmarkIndexAnyASCII/256:8-4 1994 394 -80.24%
BenchmarkIndexAnyASCII/256:16-4 3843 411 -89.31%
BenchmarkIndexAnyASCII/4096:1-4 8522 5873 -31.08%
BenchmarkIndexAnyASCII/4096:2-4 11253 5861 -47.92%
BenchmarkIndexAnyASCII/4096:4-4 17824 5883 -66.99%
BenchmarkIndexAnyASCII/4096:8-4 32053 5871 -81.68%
BenchmarkIndexAnyASCII/4096:16-4 60512 5888 -90.27%
BenchmarkTrimASCII/1:1-4 79.5 70.8 -10.94%
BenchmarkTrimASCII/1:2-4 79.0 105 +32.91%
BenchmarkTrimASCII/1:4-4 79.6 109 +36.93%
BenchmarkTrimASCII/1:8-4 78.8 118 +49.75%
BenchmarkTrimASCII/1:16-4 80.2 132 +64.59%
BenchmarkTrimASCII/16:1-4 243 116 -52.26%
BenchmarkTrimASCII/16:2-4 243 171 -29.63%
BenchmarkTrimASCII/16:4-4 243 176 -27.57%
BenchmarkTrimASCII/16:8-4 241 184 -23.65%
BenchmarkTrimASCII/16:16-4 238 199 -16.39%
BenchmarkTrimASCII/256:1-4 2580 840 -67.44%
BenchmarkTrimASCII/256:2-4 2603 1175 -54.86%
BenchmarkTrimASCII/256:4-4 2572 1188 -53.81%
BenchmarkTrimASCII/256:8-4 2550 1191 -53.29%
BenchmarkTrimASCII/256:16-4 2585 1208 -53.27%
BenchmarkTrimASCII/4096:1-4 39773 12181 -69.37%
BenchmarkTrimASCII/4096:2-4 39946 17231 -56.86%
BenchmarkTrimASCII/4096:4-4 39641 17179 -56.66%
BenchmarkTrimASCII/4096:8-4 39835 17175 -56.88%
BenchmarkTrimASCII/4096:16-4 40229 17215 -57.21%
== strings package ==
benchmark old ns/op new ns/op delta
BenchmarkIndexAnyASCII/1:1-4 5.94 4.97 -16.33%
BenchmarkIndexAnyASCII/1:2-4 5.94 5.55 -6.57%
BenchmarkIndexAnyASCII/1:4-4 7.45 7.21 -3.22%
BenchmarkIndexAnyASCII/1:8-4 10.8 10.6 -1.85%
BenchmarkIndexAnyASCII/1:16-4 17.4 17.2 -1.15%
BenchmarkIndexAnyASCII/16:1-4 36.4 32.2 -11.54%
BenchmarkIndexAnyASCII/16:2-4 49.6 34.6 -30.24%
BenchmarkIndexAnyASCII/16:4-4 77.5 37.9 -51.10%
BenchmarkIndexAnyASCII/16:8-4 138 45.5 -67.03%
BenchmarkIndexAnyASCII/16:16-4 241 59.1 -75.48%
BenchmarkIndexAnyASCII/256:1-4 509 378 -25.74%
BenchmarkIndexAnyASCII/256:2-4 720 381 -47.08%
BenchmarkIndexAnyASCII/256:4-4 1142 384 -66.37%
BenchmarkIndexAnyASCII/256:8-4 1999 391 -80.44%
BenchmarkIndexAnyASCII/256:16-4 3735 403 -89.21%
BenchmarkIndexAnyASCII/4096:1-4 7973 5824 -26.95%
BenchmarkIndexAnyASCII/4096:2-4 11432 5809 -49.19%
BenchmarkIndexAnyASCII/4096:4-4 18327 5819 -68.25%
BenchmarkIndexAnyASCII/4096:8-4 33059 5828 -82.37%
BenchmarkIndexAnyASCII/4096:16-4 59703 5817 -90.26%
BenchmarkTrimASCII/1:1-4 71.9 71.8 -0.14%
BenchmarkTrimASCII/1:2-4 73.3 103 +40.52%
BenchmarkTrimASCII/1:4-4 71.8 106 +47.63%
BenchmarkTrimASCII/1:8-4 71.2 113 +58.71%
BenchmarkTrimASCII/1:16-4 71.6 128 +78.77%
BenchmarkTrimASCII/16:1-4 152 116 -23.68%
BenchmarkTrimASCII/16:2-4 160 168 +5.00%
BenchmarkTrimASCII/16:4-4 172 170 -1.16%
BenchmarkTrimASCII/16:8-4 200 177 -11.50%
BenchmarkTrimASCII/16:16-4 254 193 -24.02%
BenchmarkTrimASCII/256:1-4 1438 864 -39.92%
BenchmarkTrimASCII/256:2-4 1551 1195 -22.95%
BenchmarkTrimASCII/256:4-4 1770 1200 -32.20%
BenchmarkTrimASCII/256:8-4 2195 1216 -44.60%
BenchmarkTrimASCII/256:16-4 3054 1224 -59.92%
BenchmarkTrimASCII/4096:1-4 21726 12557 -42.20%
BenchmarkTrimASCII/4096:2-4 23586 17508 -25.77%
BenchmarkTrimASCII/4096:4-4 26898 17510 -34.90%
BenchmarkTrimASCII/4096:8-4 33714 17595 -47.81%
BenchmarkTrimASCII/4096:16-4 47429 17700 -62.68%
The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.
Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-20 03:16:22 -07:00
|
|
|
|
func BenchmarkTrimASCII(b *testing.B) {
|
|
|
|
|
|
cs := "0123456789abcdef"
|
|
|
|
|
|
for k := 1; k <= 4096; k <<= 4 {
|
|
|
|
|
|
for j := 1; j <= 16; j <<= 1 {
|
|
|
|
|
|
b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
|
|
|
|
|
|
x := Repeat([]byte(cs[:j]), k) // Always matches set
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Trim(x[:k], cs[:j])
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-11-04 10:19:53 -07:00
|
|
|
|
|
2021-05-29 19:11:37 -07:00
|
|
|
|
func BenchmarkTrimByte(b *testing.B) {
|
|
|
|
|
|
x := []byte(" the quick brown fox ")
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Trim(x, " ")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-04 10:19:53 -07:00
|
|
|
|
func BenchmarkIndexPeriodic(b *testing.B) {
|
|
|
|
|
|
key := []byte{1, 1}
|
|
|
|
|
|
for _, skip := range [...]int{2, 4, 8, 16, 32, 64} {
|
|
|
|
|
|
b.Run(fmt.Sprintf("IndexPeriodic%d", skip), func(b *testing.B) {
|
|
|
|
|
|
buf := make([]byte, 1<<16)
|
|
|
|
|
|
for i := 0; i < len(buf); i += skip {
|
|
|
|
|
|
buf[i] = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
Index(buf, key)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-10-31 10:04:03 +01:00
|
|
|
|
|
|
|
|
|
|
func TestClone(t *testing.T) {
|
|
|
|
|
|
var cloneTests = [][]byte{
|
|
|
|
|
|
[]byte(nil),
|
|
|
|
|
|
[]byte{},
|
|
|
|
|
|
Clone([]byte{}),
|
|
|
|
|
|
[]byte(strings.Repeat("a", 42))[:0],
|
|
|
|
|
|
[]byte(strings.Repeat("a", 42))[:0:0],
|
|
|
|
|
|
[]byte("short"),
|
|
|
|
|
|
[]byte(strings.Repeat("a", 42)),
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, input := range cloneTests {
|
|
|
|
|
|
clone := Clone(input)
|
|
|
|
|
|
if !Equal(clone, input) {
|
|
|
|
|
|
t.Errorf("Clone(%q) = %q; want %q", input, clone, input)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if input == nil && clone != nil {
|
|
|
|
|
|
t.Errorf("Clone(%#v) return value should be equal to nil slice.", input)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if input != nil && clone == nil {
|
|
|
|
|
|
t.Errorf("Clone(%#v) return value should not be equal to nil slice.", input)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-03 14:20:20 +08:00
|
|
|
|
if cap(input) != 0 && unsafe.SliceData(input) == unsafe.SliceData(clone) {
|
2021-10-31 10:04:03 +01:00
|
|
|
|
t.Errorf("Clone(%q) return value should not reference inputs backing memory.", input)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|