bytes.IndexByte is heavily optimized.
Use it in findnull.
name old time/op new time/op delta
GoString-8 65.5ns ± 1% 40.2ns ± 1% -38.62% (p=0.000 n=19+19)
findnull is also used in gostringnocopy,
which is used in many hot spots in the runtime.
Fixes #23830
Change-Id: I2e6cb279c7d8078f8844065de684cc3567fe89d7
Reviewed-on: https://go-review.googlesource.com/97523
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
int x;
};
+const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
}
}
+var sinkString string
+
+func benchGoString(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkString = C.GoString(C.cstr)
+ }
+ const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
+ if sinkString != want {
+ b.Fatalf("%q != %q", sinkString, want)
+ }
+}
+
// Issue 2470.
func testUnsignedInt(t *testing.T) {
a := (int64)(C.UINT32VAL)
func Test21897(t *testing.T) { test21897(t) }
func Test22906(t *testing.T) { test22906(t) }
-func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
+func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
+func BenchmarkGoString(b *testing.B) { benchGoString(b) }
// strings.IndexByte is implemented in runtime/asm_$goarch.s
// but amusingly we need go:linkname to get access to it here in the runtime.
//go:linkname stringsIndexByte strings.IndexByte
+//go:noescape
func stringsIndexByte(s string, c byte) int
// panicwrap generates a panic for a call to a wrapped value method
if s == nil {
return 0
}
- p := (*[maxAlloc/2 - 1]byte)(unsafe.Pointer(s))
- l := 0
- for p[l] != 0 {
- l++
- }
- return l
+ ss := stringStruct{unsafe.Pointer(s), maxAlloc/2 - 1}
+ t := *(*string)(unsafe.Pointer(&ss))
+ return stringsIndexByte(t, 0)
}
func findnullw(s *uint16) int {