[performance-profiler] Skip event cloning in convert processor copy-mode rollback path
- Dominant language
- Go
- Stars
- 12.7k
- Forks
- 5k
- Avg merge
- 2d 15m
- Merged PRs (30d)
- 385
Description
## Hot Path
`libbeat/processors/convert/convert.go:79-106` in `(*processor).Run` cloned the event whenever `len(p.Fields) > 1 && p.FailOnError`, even in copy-mode cases where rollback safety does not require a clone.
The hot path is exercised by `BenchmarkTestConvertRun` in `libbeat/processors/convert/convert_test.go:474-515`.
## Profiling Data
**Before:**
```text
$ cd /tmp/gh-aw/agent/beats-base/libbeat/processors/convert
$ go test -bench='^BenchmarkTestConvertRun$' -benchmem -count=5
goos: linux
goarch: amd64
pkg: github.com/elastic/beats/v7/libbeat/processors/convert
cpu: AMD EPYC 7763 64-Core Processor
BenchmarkTestConvertRun-4 880317 1494 ns/op 2320 B/op 17 allocs/op
BenchmarkTestConvertRun-4 865906 1711 ns/op 2320 B/op 17 allocs/op
BenchmarkTestConvertRun-4 624973 1608 ns/op 2320 B/op 17 allocs/op
BenchmarkTestConvertRun-4 847501 1473 ns/op 2320 B/op 17 allocs/op
BenchmarkTestConvertRun-4 887674 1430 ns/op 2320 B/op 17 allocs/op
PASS
ok github.com/elastic/beats/v7/libbeat/processors/convert 6.431s
```
## Proposed Change
Add a fast path to skip `event.Clone()` when the configuration is rollback-safe without cloning:
- Precompute eligible targets in `newConvert` (`cloneCheckTargets`) (`libbeat/processors/convert/convert.go:61-72`, `127-150`)
- In `Run`, clone only when `!p.canSkipClone(event)` (`libbeat/processors/convert/convert.go:90-98`)
- Ensure safety by requiring copy mode, fail-on-error, multiple fields, and non-overlapping target paths (`libbeat/processors/convert/convert.go:108-125`)
Validation coverage added at `libbeat/processors/convert/convert_test.go:289-307` (`TestConvertRunNoCloneForIndependentCopyTargets`).
## Results
**After:**
```text
$ cd /home/runner/work/beats/beats/libbeat/processors/convert
$ go test -bench='^BenchmarkTestConvertRun$' -benchmem -count=5
goos: linux
goarch: amd64
pkg: github.com/elastic/beats/v7/libbeat/processors/convert
cpu: AMD EPYC 7763 64-Core Processor
BenchmarkTestConvertRun-4 1000000 1064 ns/op 1200 B/op 9 allocs/op
BenchmarkTestConvertRun-4 1000000 1293 ns/op 1200 B/op 9 allocs/op
BenchmarkTestConvertRun-4 1105956 1057 ns/op 1200 B/op 9 allocs/op
BenchmarkTestConvertRun-4 1000000 1065 ns/op 1200 B/op 9 allocs/op
BenchmarkTestConvertRun-4 1000000 1066 ns/op 1200 B/op 9 allocs/op
PASS
ok github.com/elastic/beats/v7/libbeat/processors/convert 6.438s
```
**Improvement:**
- `ns/op` mean: `1543.2 -> 1109.0` (**28.14% faster**)
- `B/op`: `2320 -> 1200` (**48.28% lower**)
- `allocs/op`: `17 -> 9` (**47.06% lower**)
## Verification
- `go test ./libbeat/processors/convert/...` passed.
- Added focused regression test (`TestConvertRunNoCloneForIndependentCopyTargets`) confirming behavior is preserved for the new fast path.
## Evidence
- Before and after used the same benchmark command (`go test -bench='^BenchmarkTestConvertRun$' -benchmem -count=5`) against different code states.
- Hot path and change locations:
- `libbeat/processors/convert/convert.go:79-125`
- `libbeat/processors/convert/convert.go:127-150`
- `libbeat/processors/convert/convert_test.go:289-307`
- Duplicate check performed against `/tmp/previous-findings.json` and open issue search; no matching existing convert-processor profiler issue found.
---
[What is this?](https://ela.st/github-ai-tools) | [From workflow: Performance Profiler](https://github.com/elastic/beats/actions/runs/26406812272)
Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.
> - [x] expires on Jun 1, 2026, 3:17 PM UTC
Contributor guide
Research direction
Start in libbeat/processors/convert/convert.go, especially newConvert, (*processor).Run, and the clone-safety checks described in the issue. Read the focused regression test at libbeat/processors/convert/convert_test.go:289-307, then run the convert package tests and BenchmarkTestConvertRun. Done means rollback-safe copy-mode cases avoid cloning while behavior and benchmark coverage remain valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- performance
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100