elastic / elastic/beats

[performance-profiler] Skip event cloning in convert processor copy-mode rollback path

Open
#50,906 1 comment 0 reactions 0 assignees View on GitHub
needs_team
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.