mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: replace stringStruct with unsafe.String where appropriate
Simplify the code a bit, no significant performance changes. name old time/op new time/op delta HashStringSpeed-8 9.64ns ±11% 8.91ns ± 9% -7.60% (p=0.007 n=10+10) HashStringArraySpeed-8 19.8ns ± 3% 19.5ns ± 2% ~ (p=0.085 n=10+10) MapStringKeysEight_16-8 10.7ns ± 3% 10.2ns ± 2% -4.48% (p=0.000 n=10+10) MapStringKeysEight_32-8 8.89ns ± 3% 8.71ns ± 3% ~ (p=0.082 n=9+10) MapStringKeysEight_64-8 8.84ns ± 2% 8.60ns ± 3% -2.73% (p=0.004 n=9+10) MapStringKeysEight_1M-8 8.90ns ± 3% 8.62ns ± 3% -3.15% (p=0.000 n=10+10) MapStringConversion/32/simple-8 8.62ns ± 3% 8.61ns ± 2% ~ (p=0.895 n=10+10) MapStringConversion/32/struct-8 8.53ns ± 2% 8.63ns ± 2% ~ (p=0.123 n=10+10) MapStringConversion/32/array-8 8.54ns ± 2% 8.50ns ± 1% ~ (p=0.590 n=9+9) MapStringConversion/64/simple-8 8.44ns ± 2% 8.38ns ± 2% ~ (p=0.353 n=10+10) MapStringConversion/64/struct-8 8.41ns ± 2% 8.48ns ± 2% ~ (p=0.143 n=10+10) MapStringConversion/64/array-8 8.42ns ± 2% 8.44ns ± 2% ~ (p=0.739 n=10+10) MapInterfaceString-8 13.6ns ±26% 13.6ns ±20% ~ (p=0.736 n=10+9) AppendGrowString-8 38.9ms ± 9% 40.2ms ±13% ~ (p=0.481 n=10+10) CompareStringEqual-8 3.03ns ± 2% 2.86ns ± 3% -5.58% (p=0.000 n=10+10) CompareStringIdentical-8 1.20ns ± 3% 1.01ns ± 4% -16.16% (p=0.000 n=10+10) CompareStringSameLength-8 2.11ns ± 3% 1.85ns ± 3% -12.33% (p=0.000 n=10+10) CompareStringDifferentLength-8 0.30ns ± 0% 0.30ns ± 0% ~ (p=0.508 n=10+9) CompareStringBigUnaligned-8 43.0µs ± 1% 42.8µs ± 2% ~ (p=0.165 n=10+10) CompareStringBig-8 43.2µs ± 2% 43.4µs ± 2% ~ (p=0.661 n=9+10) ConcatStringAndBytes-8 15.1ns ± 1% 14.9ns ± 1% -1.57% (p=0.001 n=8+10) SliceByteToString/1-8 2.45ns ± 2% 2.39ns ± 2% -2.64% (p=0.000 n=10+10) SliceByteToString/2-8 10.9ns ± 2% 10.8ns ± 4% ~ (p=0.060 n=10+10) SliceByteToString/4-8 11.9ns ± 0% 11.8ns ± 1% -0.97% (p=0.000 n=8+8) SliceByteToString/8-8 13.9ns ± 1% 13.9ns ± 1% +0.57% (p=0.009 n=9+9) SliceByteToString/16-8 18.0ns ± 3% 18.6ns ± 5% +2.78% (p=0.001 n=9+10) SliceByteToString/32-8 20.1ns ± 3% 20.5ns ± 5% +2.10% (p=0.034 n=10+10) SliceByteToString/64-8 24.3ns ± 3% 24.9ns ± 3% +2.28% (p=0.001 n=9+10) SliceByteToString/128-8 33.8ns ± 1% 34.5ns ± 4% ~ (p=0.264 n=8+10) Updates #54854 Change-Id: I7ce57a92c5f590fa8cb31a48969d281147eb05f1 Reviewed-on: https://go-review.googlesource.com/c/go/+/428759 Reviewed-by: hopehook <hopehook@golangcn.org> Reviewed-by: Keith Randall <khr@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
d36466fe2a
commit
7ffbcd1987
4 changed files with 23 additions and 46 deletions
|
|
@ -292,21 +292,19 @@ func (l *dlogger) s(x string) *dlogger {
|
|||
if !dlogEnabled {
|
||||
return l
|
||||
}
|
||||
str := stringStructOf(&x)
|
||||
|
||||
strData := unsafe.StringData(x)
|
||||
datap := &firstmoduledata
|
||||
if len(x) > 4 && datap.etext <= uintptr(str.str) && uintptr(str.str) < datap.end {
|
||||
if len(x) > 4 && datap.etext <= uintptr(unsafe.Pointer(strData)) && uintptr(unsafe.Pointer(strData)) < datap.end {
|
||||
// String constants are in the rodata section, which
|
||||
// isn't recorded in moduledata. But it has to be
|
||||
// somewhere between etext and end.
|
||||
l.w.byte(debugLogConstString)
|
||||
l.w.uvarint(uint64(str.len))
|
||||
l.w.uvarint(uint64(uintptr(str.str) - datap.etext))
|
||||
l.w.uvarint(uint64(len(x)))
|
||||
l.w.uvarint(uint64(uintptr(unsafe.Pointer(strData)) - datap.etext))
|
||||
} else {
|
||||
l.w.byte(debugLogString)
|
||||
var b []byte
|
||||
bb := (*slice)(unsafe.Pointer(&b))
|
||||
bb.array = str.str
|
||||
bb.len, bb.cap = str.len, str.len
|
||||
b := unsafe.Slice(strData, len(x))
|
||||
if len(b) > debugLogStringLimit {
|
||||
b = b[:debugLogStringLimit]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,8 +156,7 @@ func dumpslice(b []byte) {
|
|||
}
|
||||
|
||||
func dumpstr(s string) {
|
||||
sp := stringStructOf(&s)
|
||||
dumpmemrange(sp.str, uintptr(sp.len))
|
||||
dumpmemrange(unsafe.Pointer(unsafe.StringData(s)), uintptr(len(s)))
|
||||
}
|
||||
|
||||
// dump information for a type
|
||||
|
|
@ -197,14 +196,12 @@ func dumptype(t *_type) {
|
|||
if x := t.uncommon(); x == nil || t.nameOff(x.pkgpath).name() == "" {
|
||||
dumpstr(t.string())
|
||||
} else {
|
||||
pkgpathstr := t.nameOff(x.pkgpath).name()
|
||||
pkgpath := stringStructOf(&pkgpathstr)
|
||||
namestr := t.name()
|
||||
name := stringStructOf(&namestr)
|
||||
dumpint(uint64(uintptr(pkgpath.len) + 1 + uintptr(name.len)))
|
||||
dwrite(pkgpath.str, uintptr(pkgpath.len))
|
||||
pkgpath := t.nameOff(x.pkgpath).name()
|
||||
name := t.name()
|
||||
dumpint(uint64(uintptr(len(pkgpath)) + 1 + uintptr(len(name))))
|
||||
dwrite(unsafe.Pointer(unsafe.StringData(pkgpath)), uintptr(len(pkgpath)))
|
||||
dwritebyte('.')
|
||||
dwrite(name.str, uintptr(name.len))
|
||||
dwrite(unsafe.Pointer(unsafe.StringData(name)), uintptr(len(name)))
|
||||
}
|
||||
dumpbool(t.kind&kindDirectIface == 0 || t.ptrdata != 0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func concatstring5(buf *tmpBuf, a0, a1, a2, a3, a4 string) string {
|
|||
// n is the length of the slice.
|
||||
// Buf is a fixed-size buffer for the result,
|
||||
// it is not nil if the result does not escape.
|
||||
func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
|
||||
func slicebytetostring(buf *tmpBuf, ptr *byte, n int) string {
|
||||
if n == 0 {
|
||||
// Turns out to be a relatively common case.
|
||||
// Consider that you want to parse out data between parens in "foo()bar",
|
||||
|
|
@ -102,9 +102,7 @@ func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
|
|||
if goarch.BigEndian {
|
||||
p = add(p, 7)
|
||||
}
|
||||
stringStructOf(&str).str = p
|
||||
stringStructOf(&str).len = 1
|
||||
return
|
||||
return unsafe.String((*byte)(p), 1)
|
||||
}
|
||||
|
||||
var p unsafe.Pointer
|
||||
|
|
@ -113,16 +111,14 @@ func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
|
|||
} else {
|
||||
p = mallocgc(uintptr(n), nil, false)
|
||||
}
|
||||
stringStructOf(&str).str = p
|
||||
stringStructOf(&str).len = n
|
||||
memmove(p, unsafe.Pointer(ptr), uintptr(n))
|
||||
return
|
||||
return unsafe.String((*byte)(p), n)
|
||||
}
|
||||
|
||||
// stringDataOnStack reports whether the string's data is
|
||||
// stored on the current goroutine's stack.
|
||||
func stringDataOnStack(s string) bool {
|
||||
ptr := uintptr(stringStructOf(&s).str)
|
||||
ptr := uintptr(unsafe.Pointer(unsafe.StringData(s)))
|
||||
stk := getg().stack
|
||||
return stk.lo <= ptr && ptr < stk.hi
|
||||
}
|
||||
|
|
@ -151,7 +147,7 @@ func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) {
|
|||
// where k is []byte, T1 to Tn is a nesting of struct and array literals.
|
||||
// - Used for "<"+string(b)+">" concatenation where b is []byte.
|
||||
// - Used for string(b)=="foo" comparison where b is []byte.
|
||||
func slicebytetostringtmp(ptr *byte, n int) (str string) {
|
||||
func slicebytetostringtmp(ptr *byte, n int) string {
|
||||
if raceenabled && n > 0 {
|
||||
racereadrangepc(unsafe.Pointer(ptr),
|
||||
uintptr(n),
|
||||
|
|
@ -164,9 +160,7 @@ func slicebytetostringtmp(ptr *byte, n int) (str string) {
|
|||
if asanenabled && n > 0 {
|
||||
asanread(unsafe.Pointer(ptr), uintptr(n))
|
||||
}
|
||||
stringStructOf(&str).str = unsafe.Pointer(ptr)
|
||||
stringStructOf(&str).len = n
|
||||
return
|
||||
return unsafe.String(ptr, n)
|
||||
}
|
||||
|
||||
func stringtoslicebyte(buf *tmpBuf, s string) []byte {
|
||||
|
|
@ -271,13 +265,7 @@ func intstring(buf *[4]byte, v int64) (s string) {
|
|||
// b to set the string contents and then drop b.
|
||||
func rawstring(size int) (s string, b []byte) {
|
||||
p := mallocgc(uintptr(size), nil, false)
|
||||
|
||||
stringStructOf(&s).str = p
|
||||
stringStructOf(&s).len = size
|
||||
|
||||
*(*slice)(unsafe.Pointer(&b)) = slice{p, size, size}
|
||||
|
||||
return
|
||||
return unsafe.String((*byte)(p), size), unsafe.Slice((*byte)(p), size)
|
||||
}
|
||||
|
||||
// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ func (n name) readvarint(off int) (int, int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (n name) name() (s string) {
|
||||
func (n name) name() string {
|
||||
if n.bytes == nil {
|
||||
return ""
|
||||
}
|
||||
|
|
@ -462,22 +462,16 @@ func (n name) name() (s string) {
|
|||
if l == 0 {
|
||||
return ""
|
||||
}
|
||||
hdr := (*stringStruct)(unsafe.Pointer(&s))
|
||||
hdr.str = unsafe.Pointer(n.data(1 + i))
|
||||
hdr.len = l
|
||||
return
|
||||
return unsafe.String(n.data(1+i), l)
|
||||
}
|
||||
|
||||
func (n name) tag() (s string) {
|
||||
func (n name) tag() string {
|
||||
if *n.data(0)&(1<<1) == 0 {
|
||||
return ""
|
||||
}
|
||||
i, l := n.readvarint(1)
|
||||
i2, l2 := n.readvarint(1 + i + l)
|
||||
hdr := (*stringStruct)(unsafe.Pointer(&s))
|
||||
hdr.str = unsafe.Pointer(n.data(1 + i + l + i2))
|
||||
hdr.len = l2
|
||||
return
|
||||
return unsafe.String(n.data(1+i+l+i2), l2)
|
||||
}
|
||||
|
||||
func (n name) pkgPath() string {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue