mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: improve string iteration performance
Generate a for loop for ranging over strings that only needs to call the runtime function charntorune for non ASCII characters. This provides faster iteration over ASCII characters and slightly faster iteration for other characters. The runtime function charntorune is changed to take an index from where to start decoding and returns the index after the last byte belonging to the decoded rune. All call sites of charntorune in the runtime are replaced by a for loop that will be transformed by the compiler instead of calling the charntorune function directly. go binary size decreases by 80 bytes. godoc binary size increases by around 4 kilobytes. runtime: name old time/op new time/op delta RuneIterate/range/ASCII-4 43.7ns ± 3% 10.3ns ± 4% -76.33% (p=0.000 n=44+45) RuneIterate/range/Japanese-4 72.5ns ± 2% 62.8ns ± 2% -13.41% (p=0.000 n=49+50) RuneIterate/range1/ASCII-4 43.5ns ± 2% 10.4ns ± 3% -76.18% (p=0.000 n=50+50) RuneIterate/range1/Japanese-4 72.5ns ± 2% 62.9ns ± 2% -13.26% (p=0.000 n=50+49) RuneIterate/range2/ASCII-4 43.5ns ± 3% 10.3ns ± 2% -76.22% (p=0.000 n=48+47) RuneIterate/range2/Japanese-4 72.4ns ± 2% 62.7ns ± 2% -13.47% (p=0.000 n=50+50) strings: name old time/op new time/op delta IndexRune-4 64.7ns ± 5% 22.4ns ± 3% -65.43% (p=0.000 n=25+21) MapNoChanges-4 269ns ± 2% 157ns ± 2% -41.46% (p=0.000 n=23+24) Fields-4 23.0ms ± 2% 19.7ms ± 2% -14.35% (p=0.000 n=25+25) FieldsFunc-4 23.1ms ± 2% 19.6ms ± 2% -14.94% (p=0.000 n=25+24) name old speed new speed delta Fields-4 45.6MB/s ± 2% 53.2MB/s ± 2% +16.87% (p=0.000 n=24+25) FieldsFunc-4 45.5MB/s ± 2% 53.5MB/s ± 2% +17.57% (p=0.000 n=25+24) Updates #13162 Change-Id: I79ffaf828d82bf9887592f08e5cad883e9f39701 Reviewed-on: https://go-review.googlesource.com/27853 TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Martin Möhrmann <martisch@uos.de>
This commit is contained in:
parent
0d7a2241cb
commit
0dae9dfb08
8 changed files with 290 additions and 224 deletions
|
|
@ -163,12 +163,10 @@ func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
|
|||
// two passes.
|
||||
// unlike slicerunetostring, no race because strings are immutable.
|
||||
n := 0
|
||||
t := s
|
||||
for len(s) > 0 {
|
||||
_, k := charntorune(s)
|
||||
s = s[k:]
|
||||
for range s {
|
||||
n++
|
||||
}
|
||||
|
||||
var a []rune
|
||||
if buf != nil && n <= len(buf) {
|
||||
*buf = [tmpStringBufSize]rune{}
|
||||
|
|
@ -176,10 +174,9 @@ func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
|
|||
} else {
|
||||
a = rawruneslice(n)
|
||||
}
|
||||
|
||||
n = 0
|
||||
for len(t) > 0 {
|
||||
r, k := charntorune(t)
|
||||
t = t[k:]
|
||||
for _, r := range s {
|
||||
a[n] = r
|
||||
n++
|
||||
}
|
||||
|
|
@ -244,42 +241,6 @@ func intstring(buf *[4]byte, v int64) string {
|
|||
return s[:n]
|
||||
}
|
||||
|
||||
// stringiter returns the index of the next
|
||||
// rune after the rune that starts at s[k].
|
||||
func stringiter(s string, k int) int {
|
||||
if k >= len(s) {
|
||||
// 0 is end of iteration
|
||||
return 0
|
||||
}
|
||||
|
||||
c := s[k]
|
||||
if c < runeself {
|
||||
return k + 1
|
||||
}
|
||||
|
||||
// multi-char rune
|
||||
_, n := charntorune(s[k:])
|
||||
return k + n
|
||||
}
|
||||
|
||||
// stringiter2 returns the rune that starts at s[k]
|
||||
// and the index where the next rune starts.
|
||||
func stringiter2(s string, k int) (int, rune) {
|
||||
if k >= len(s) {
|
||||
// 0 is end of iteration
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
c := s[k]
|
||||
if c < runeself {
|
||||
return k + 1, rune(c)
|
||||
}
|
||||
|
||||
// multi-char rune
|
||||
r, n := charntorune(s[k:])
|
||||
return k + n, r
|
||||
}
|
||||
|
||||
// rawstring allocates storage for a new string. The returned
|
||||
// string and byte slice both refer to the same storage.
|
||||
// The storage is not zeroed. Callers should use
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue