aboutsummaryrefslogtreecommitdiff
path: root/src/bytes
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytes')
-rw-r--r--src/bytes/bytes.go21
1 files changed, 11 insertions, 10 deletions
diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go
index 16d1854c44..aa07b9fbc1 100644
--- a/src/bytes/bytes.go
+++ b/src/bytes/bytes.go
@@ -458,8 +458,10 @@ func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
spans := make([]span, 0, 32)
// Find the field start and end indices.
- wasField := false
- fromIndex := 0
+ // Doing this in a separate pass (rather than slicing the string s
+ // and collecting the result substrings right away) is significantly
+ // more efficient, possibly due to cache effects.
+ start := -1 // valid span start if >= 0
for i := 0; i < len(s); {
size := 1
r := rune(s[i])
@@ -467,22 +469,21 @@ func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
r, size = utf8.DecodeRune(s[i:])
}
if f(r) {
- if wasField {
- spans = append(spans, span{start: fromIndex, end: i})
- wasField = false
+ if start >= 0 {
+ spans = append(spans, span{start, i})
+ start = -1
}
} else {
- if !wasField {
- fromIndex = i
- wasField = true
+ if start < 0 {
+ start = i
}
}
i += size
}
// Last field might end at EOF.
- if wasField {
- spans = append(spans, span{fromIndex, len(s)})
+ if start >= 0 {
+ spans = append(spans, span{start, len(s)})
}
// Create subslices from recorded field indices.