aboutsummaryrefslogtreecommitdiff
path: root/src/bytes
diff options
context:
space:
mode:
authorJulien Cretel <jub0bsinthecloud@gmail.com>2025-05-13 11:11:13 +0000
committerGopher Robot <gobot@golang.org>2025-05-14 11:07:32 -0700
commit14fc54fc5735163abf7694b4efa2b7998c6696e2 (patch)
treefa3fd0139de13691ed433f9e003d68146229c5d1 /src/bytes
parent9856afa77042d901288845f31c79885ba68da464 (diff)
downloadgo-14fc54fc5735163abf7694b4efa2b7998c6696e2.tar.xz
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: 344934071f3220a1afea3def306dadfee720d311 GitHub-Pull-Request: golang/go#73685 Reviewed-on: https://go-review.googlesource.com/c/go/+/672175 Reviewed-by: qiu laidongfeng2 <2645477756@qq.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/bytes')
-rw-r--r--src/bytes/iter.go19
1 files changed, 7 insertions, 12 deletions
diff --git a/src/bytes/iter.go b/src/bytes/iter.go
index e3af4d2f13..b2abb2c9ba 100644
--- a/src/bytes/iter.go
+++ b/src/bytes/iter.go
@@ -31,23 +31,18 @@ func Lines(s []byte) iter.Seq[[]byte] {
}
}
-// explodeSeq returns an iterator over the runes in s.
-func explodeSeq(s []byte, yield func([]byte) bool) {
- for len(s) > 0 {
- _, size := utf8.DecodeRune(s)
- if !yield(s[:size:size]) {
- return
- }
- s = s[size:]
- }
-}
-
// splitSeq is SplitSeq or SplitAfterSeq, configured by how many
// bytes of sep to include in the results (none or all).
func splitSeq(s, sep []byte, sepSave int) iter.Seq[[]byte] {
return func(yield func([]byte) bool) {
if len(sep) == 0 {
- explodeSeq(s, yield)
+ for len(s) > 0 {
+ _, size := utf8.DecodeRune(s)
+ if !yield(s[:size:size]) {
+ return
+ }
+ s = s[size:]
+ }
return
}
for {