]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: replace stringStruct with unsafe.String where appropriate
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 7 Sep 2022 06:23:10 +0000 (13:23 +0700)
committerGopher Robot <gobot@golang.org>
Tue, 13 Sep 2022 16:42:28 +0000 (16:42 +0000)
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>
src/runtime/debuglog.go
src/runtime/heapdump.go
src/runtime/string.go
src/runtime/type.go

index 83d5a3e9e64f0317eced85b992b93c887958f890..1fc7dd5555334d557e576bf0a5b1c3df78887556 100644 (file)
@@ -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]
                }
index 0268e25595295f4e583b2d2930673234cb1f50da..322838ab880c276d048ba8a162d221bd33de63d4 100644 (file)
@@ -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)
 }
index 359a5658c5acf78b1bc98cd0a88f96021d27376e..eaade640c411dd42a94a5becc027a394fc05173f 100644 (file)
@@ -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.
index e8e7819ecfe6cd218262f18aa8afe3b5604ba86f..1c6103e6ede8bf2e99a60ff9e8cd573043f49d01 100644 (file)
@@ -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 {