Skip to content

Commit 14fc54f

Browse files
jub0bsgopherbot
authored andcommitted
bytes, strings: speed up Split{,After}Seq
CL 669735 brought a welcome performance boost to splitSeq; however, it rendered explodeSeq ineligible for inlining and failed to update that function's doc comment. This CL inlines the call to explodeSeq in splitSeq, thereby unlocking a further speedup in the case of an empty separator, and removes function explodeSeq altogether. Some benchmarks results: goos: darwin goarch: amd64 pkg: strings cpu: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz │ old │ new │ │ sec/op │ sec/op vs base │ SplitSeqEmptySeparator-8 5.136m ± 6% 3.180m ± 6% -38.09% (p=0.000 n=20) SplitSeqSingleByteSeparator-8 995.9µ ± 1% 988.4µ ± 0% -0.75% (p=0.000 n=20) SplitSeqMultiByteSeparator-8 593.1µ ± 2% 591.7µ ± 1% ~ (p=0.253 n=20) SplitAfterSeqEmptySeparator-8 5.554m ± 3% 3.432m ± 2% -38.20% (p=0.000 n=20) SplitAfterSeqSingleByteSeparator-8 997.4µ ± 0% 1000.0µ ± 8% ~ (p=0.121 n=20) SplitAfterSeqMultiByteSeparator-8 591.7µ ± 1% 588.9µ ± 0% -0.48% (p=0.004 n=20) geomean 1.466m 1.247m -14.97% │ old │ new │ │ B/op │ B/op vs base │ SplitSeqEmptySeparator-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹ SplitSeqSingleByteSeparator-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹ SplitSeqMultiByteSeparator-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹ SplitAfterSeqEmptySeparator-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹ SplitAfterSeqSingleByteSeparator-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹ SplitAfterSeqMultiByteSeparator-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean Change-Id: I5767b68dc1a4fbcb2ac20683830a49ee3eb1bee1 GitHub-Last-Rev: 3449340 GitHub-Pull-Request: #73685 Reviewed-on: https://go-review.googlesource.com/c/go/+/672175 Reviewed-by: qiu laidongfeng2 <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> Auto-Submit: Keith Randall <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 9856afa commit 14fc54f

File tree

2 files changed

+14
-24
lines changed

2 files changed

+14
-24
lines changed

src/bytes/iter.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,18 @@ func Lines(s []byte) iter.Seq[[]byte] {
3131
}
3232
}
3333

34-
// explodeSeq returns an iterator over the runes in s.
35-
func explodeSeq(s []byte, yield func([]byte) bool) {
36-
for len(s) > 0 {
37-
_, size := utf8.DecodeRune(s)
38-
if !yield(s[:size:size]) {
39-
return
40-
}
41-
s = s[size:]
42-
}
43-
}
44-
4534
// splitSeq is SplitSeq or SplitAfterSeq, configured by how many
4635
// bytes of sep to include in the results (none or all).
4736
func splitSeq(s, sep []byte, sepSave int) iter.Seq[[]byte] {
4837
return func(yield func([]byte) bool) {
4938
if len(sep) == 0 {
50-
explodeSeq(s, yield)
39+
for len(s) > 0 {
40+
_, size := utf8.DecodeRune(s)
41+
if !yield(s[:size:size]) {
42+
return
43+
}
44+
s = s[size:]
45+
}
5146
return
5247
}
5348
for {

src/strings/iter.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,18 @@ func Lines(s string) iter.Seq[string] {
3131
}
3232
}
3333

34-
// explodeSeq returns an iterator over the runes in s.
35-
func explodeSeq(s string, yield func(string) bool) {
36-
for len(s) > 0 {
37-
_, size := utf8.DecodeRuneInString(s)
38-
if !yield(s[:size]) {
39-
return
40-
}
41-
s = s[size:]
42-
}
43-
}
44-
4534
// splitSeq is SplitSeq or SplitAfterSeq, configured by how many
4635
// bytes of sep to include in the results (none or all).
4736
func splitSeq(s, sep string, sepSave int) iter.Seq[string] {
4837
return func(yield func(string) bool) {
4938
if len(sep) == 0 {
50-
explodeSeq(s, yield)
39+
for len(s) > 0 {
40+
_, size := utf8.DecodeRuneInString(s)
41+
if !yield(s[:size]) {
42+
return
43+
}
44+
s = s[size:]
45+
}
5146
return
5247
}
5348
for {

0 commit comments

Comments
 (0)