aboutsummaryrefslogtreecommitdiff
path: root/src/strings/strings.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/strings/strings.go')
-rw-r--r--src/strings/strings.go26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/strings/strings.go b/src/strings/strings.go
index 5f244d6e20..88fbeecc6f 100644
--- a/src/strings/strings.go
+++ b/src/strings/strings.go
@@ -379,25 +379,29 @@ func FieldsFunc(s string, f func(rune) bool) []string {
spans := make([]span, 0, 32)
// Find the field start and end indices.
- wasField := false
- fromIndex := 0
- for i, rune := range s {
+ // 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 end, rune := range s {
if f(rune) {
- if wasField {
- spans = append(spans, span{start: fromIndex, end: i})
- wasField = false
+ if start >= 0 {
+ spans = append(spans, span{start, end})
+ // Set start to a negative value.
+ // Note: using -1 here consistently and reproducibly
+ // slows down this code by a several percent on amd64.
+ start = ^start
}
} else {
- if !wasField {
- fromIndex = i
- wasField = true
+ if start < 0 {
+ start = end
}
}
}
// 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 strings from recorded field indices.