Optimize Key.Strings by reducing memory re-allocations and simplifying control flow (#385)

This commit is contained in:
Kashish Sahu
2026-06-08 08:12:57 -04:00
committed by GitHub
parent 89efed6562
commit 360a98b83c
3 changed files with 42 additions and 21 deletions
+13
View File
@@ -114,3 +114,16 @@ func Benchmark_Key_SetValue_VisSection(b *testing.B) {
sec.Key("NAME").SetValue("10")
}
}
func Benchmark_Key_Strings_LargeArray(b *testing.B) {
c, err := Load("testdata/large_array.ini")
if err != nil {
b.Fatal(err)
}
key := c.Section("").Key("ARRAY")
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = key.Strings(",")
}
}
+26 -19
View File
@@ -15,12 +15,12 @@
package ini
import (
"bytes"
"errors"
"fmt"
"strconv"
"strings"
"time"
"unicode/utf8"
)
// Key represents a key under a section.
@@ -495,31 +495,38 @@ func (k *Key) Strings(delim string) []string {
return []string{}
}
runes := []rune(str)
vals := make([]string, 0, 2)
var buf bytes.Buffer
escape := false
idx := 0
maxParts := strings.Count(str, delim) + 1
vals := make([]string, 0, maxParts)
var buf strings.Builder
buf.Grow(len(str))
i := 0
for {
if escape {
escape = false
if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) {
if str[i] == '\\' {
i++
if i >= len(str) {
break
}
if str[i] != '\\' && !strings.HasPrefix(str[i:], delim) {
buf.WriteRune('\\')
}
buf.WriteRune(runes[idx])
} else {
if runes[idx] == '\\' {
escape = true
} else if strings.HasPrefix(string(runes[idx:]), delim) {
idx += len(delim) - 1
r, size := utf8.DecodeRuneInString(str[i:])
i += size
buf.WriteRune(r)
} else if strings.HasPrefix(str[i:], delim) {
i += len(delim)
vals = append(vals, strings.TrimSpace(buf.String()))
buf.Reset()
} else {
buf.WriteRune(runes[idx])
r, size := utf8.DecodeRuneInString(str[i:])
i += size
buf.WriteRune(r)
}
}
idx++
if idx == len(runes) {
if i >= len(str) {
break
}
}
+1
View File
File diff suppressed because one or more lines are too long