replace strings.Split(N) for strings.Cut() or alternatives
Go 1.18 and up now provides a strings.Cut() which is better suited for
splitting key/value pairs (and similar constructs), and performs better:
```go
func BenchmarkSplit(b *testing.B) {
b.ReportAllocs()
data := []string{"12hello=world", "12hello=", "12=hello", "12hello"}
for i := 0; i < b.N; i++ {
for _, s := range data {
_ = strings.SplitN(s, "=", 2)[0]
}
}
}
func BenchmarkCut(b *testing.B) {
b.ReportAllocs()
data := []string{"12hello=world", "12hello=", "12=hello", "12hello"}
for i := 0; i < b.N; i++ {
for _, s := range data {
_, _, _ = strings.Cut(s, "=")
}
}
}
```
BenchmarkSplit
BenchmarkSplit-10 8244206 128.0 ns/op 128 B/op 4 allocs/op
BenchmarkCut
BenchmarkCut-10 54411998 21.80 ns/op 0 B/op 0 allocs/op
While looking at occurrences of `strings.Split()`, I also updated some for alternatives,
or added some constraints; for cases where an specific number of items is expected, I used `strings.SplitN()`
with a suitable limit. This prevents (theoretical) unlimited splits.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -141,10 +141,10 @@ func checkContainerLog(t *testing.T, log string, messages []string) {
|
||||
lines := strings.Split(strings.TrimSpace(log), "\n")
|
||||
require.Len(t, lines, len(messages), "log line number should match")
|
||||
for i, line := range lines {
|
||||
parts := strings.SplitN(line, " ", 2)
|
||||
require.Len(t, parts, 2)
|
||||
_, err := time.Parse(time.RFC3339Nano, parts[0])
|
||||
ts, msg, ok := strings.Cut(line, " ")
|
||||
require.True(t, ok)
|
||||
_, err := time.Parse(time.RFC3339Nano, ts)
|
||||
assert.NoError(t, err, "timestamp should be in RFC3339Nano format")
|
||||
assert.Equal(t, messages[i], parts[1], "log content should match")
|
||||
assert.Equal(t, messages[i], msg, "log content should match")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,14 +509,14 @@ func PidEnvs(pid int) (map[string]string, error) {
|
||||
|
||||
res := make(map[string]string)
|
||||
for _, value := range values {
|
||||
value := strings.TrimSpace(string(value))
|
||||
value = bytes.TrimSpace(value)
|
||||
if len(value) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
parts := strings.SplitN(value, "=", 2)
|
||||
if len(parts) == 2 {
|
||||
res[parts[0]] = parts[1]
|
||||
k, v, ok := strings.Cut(string(value), "=")
|
||||
if ok {
|
||||
res[k] = v
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
|
||||
@@ -349,12 +349,7 @@ func ensureCNIAddRunning(t *testing.T, sbName string) error {
|
||||
}
|
||||
|
||||
for _, arg := range strings.Split(args, ";") {
|
||||
kv := strings.SplitN(arg, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
if kv[0] == "K8S_POD_NAME" && kv[1] == sbName {
|
||||
if arg == "K8S_POD_NAME="+sbName {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user