mirror of
https://github.com/go-ini/ini.git
synced 2026-06-19 21:46:45 +02:00
Optimize Key.Strings by reducing memory re-allocations and simplifying control flow (#385)
This commit is contained in:
@@ -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(",")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user