Hot Path
(*GenericEventConverter).normalizeSlice in libbeat/common/event.go:127-167 is a benchmarked hot path for custom typed slices (BenchmarkConvertToGenericEventCustomStringSlice in libbeat/common/event_test.go:455-462).
The baseline implementation:
appended into a zero-length []interface{} (growth allocations), and
always called normalizeValue with append(keys, strconv.Itoa(i))... (per-element key-slice/string work), even for primitive wrapper elements.
Profiling Data
Before:
go test -run '^$' -bench '^BenchmarkConvertToGenericEventCustomStringSlice$' -benchmem -count=5 -cpuprofile=cpu_before.prof -memprofile=mem_before.prof ./libbeat/common
BenchmarkConvertToGenericEventCustomStringSlice-4 1605834 725.1 ns/op 864 B/op 13 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 1689210 758.3 ns/op 864 B/op 13 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 1701534 723.4 ns/op 864 B/op 13 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 1660251 1024.0 ns/op 864 B/op 13 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 912933 3742.0 ns/op 864 B/op 13 allocs/op
Proposed Change
Use a pre-sized output slice and a primitive-kind fast path in normalizeSlice, and avoid creating indexed key paths unless an error path needs them.
libbeat/common/event.go
- var sliceValues []interface{}
+ sliceValues := make([]interface{}, n)
...
- sliceValue, err := e.normalizeValue(v.Index(i).Interface(), append(keys, strconv.Itoa(i))...)
+ elem := v.Index(i)
+ switch elem.Kind() { ... primitive fast path ... }
+ elemValue := elem.Interface()
+ sliceValue, err := e.normalizeValue(elemValue, keys...)
+ if len(err) > 0 {
+ sliceValue, err = e.normalizeValue(elemValue, append(keys, strconv.Itoa(i))...)
+ }
Also remove one allocation in Convert by switching from make([]string, 0, 10) to stack-backed var keys [10]string (libbeat/common/event.go:56-59).
Results
After:
go test -run '^$' -bench '^BenchmarkConvertToGenericEventCustomStringSlice$' -benchmem -count=5 -cpuprofile=cpu_after.prof -memprofile=mem_after.prof ./libbeat/common
BenchmarkConvertToGenericEventCustomStringSlice-4 1836873 642.0 ns/op 816 B/op 10 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 1878728 614.3 ns/op 816 B/op 10 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 2092221 578.8 ns/op 816 B/op 10 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 2070322 573.6 ns/op 816 B/op 10 allocs/op
BenchmarkConvertToGenericEventCustomStringSlice-4 1994182 595.6 ns/op 816 B/op 10 allocs/op
Improvement:
allocs/op: 13 -> 10 (23.08% fewer allocations )
B/op: 864 -> 816 (5.56% lower memory )
ns/op: first 4-run central tendency drops from ~807 to ~602 (~25% faster )
Verification
go test ./libbeat/common passes with the optimization.
Benchmark command for before/after is identical and measured against different code states.
Change is behavior-preserving (normalization semantics unchanged; only allocation/call-path reductions).
Evidence
Commands used:
go test -run '^$' -bench '^BenchmarkConvertToGenericEventCustomStringSlice$' -benchmem -count=5 -cpuprofile=cpu_before.prof -memprofile=mem_before.prof ./libbeat/common
go test -run '^$' -bench '^BenchmarkConvertToGenericEventCustomStringSlice$' -benchmem -count=5 -cpuprofile=cpu_after.prof -memprofile=mem_after.prof ./libbeat/common
go test ./libbeat/common
Code references:
libbeat/common/event.go:56-59
libbeat/common/event.go:127-167
libbeat/common/event_test.go:455-462
Note
🔒 Integrity filter blocked 18 items
The following items were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools :
github :
min-integrity : approved # merged | approved | unapproved | none
What is this? | From workflow: Performance Profiler
Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.
Hot Path
(*GenericEventConverter).normalizeSliceinlibbeat/common/event.go:127-167is a benchmarked hot path for custom typed slices (BenchmarkConvertToGenericEventCustomStringSliceinlibbeat/common/event_test.go:455-462).The baseline implementation:
[]interface{}(growth allocations), andnormalizeValuewithappend(keys, strconv.Itoa(i))...(per-element key-slice/string work), even for primitive wrapper elements.Profiling Data
Before:
Proposed Change
Use a pre-sized output slice and a primitive-kind fast path in
normalizeSlice, and avoid creating indexed key paths unless an error path needs them.Also remove one allocation in
Convertby switching frommake([]string, 0, 10)to stack-backedvar keys [10]string(libbeat/common/event.go:56-59).Results
After:
Improvement:
13 -> 10(23.08% fewer allocations)864 -> 816(5.56% lower memory)807to ~602(~25% faster)Verification
go test ./libbeat/commonpasses with the optimization.Evidence
Commands used:
go test -run '^$' -bench '^BenchmarkConvertToGenericEventCustomStringSlice$' -benchmem -count=5 -cpuprofile=cpu_before.prof -memprofile=mem_before.prof ./libbeat/commongo test -run '^$' -bench '^BenchmarkConvertToGenericEventCustomStringSlice$' -benchmem -count=5 -cpuprofile=cpu_after.prof -memprofile=mem_after.prof ./libbeat/commongo test ./libbeat/commonCode references:
libbeat/common/event.go:56-59libbeat/common/event.go:127-167libbeat/common/event_test.go:455-462Note
🔒 Integrity filter blocked 18 items
The following items were blocked because they don't meet the GitHub integrity level.
list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".list_issues: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".To allow these resources, lower
min-integrityin your GitHub frontmatter:What is this? | From workflow: Performance Profiler
Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.