Skip to content

[performance-profiler] Optimize dissect parser key suffix extraction allocationsΒ #49319

@github-actions

Description

@github-actions

Hot Path

libbeat/processors/dissect/field.go:337-359 (extractKeyParts) currently uses suffixRE.FindAllStringSubmatch(rawKey, -1) even though only one anchored match is consumed.

Profiling Data

Before:

go test ./libbeat/processors/dissect -run '^$' -bench 'BenchmarkDissect(NoConversionMultipleValues|WithConversionMultipleValues)$' -benchmem -count=5

BenchmarkDissectNoConversionMultipleValues-4   93194  12731 ns/op  5776 B/op  56 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   94039  13255 ns/op  5779 B/op  56 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   93270  12850 ns/op  5778 B/op  56 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   93493  12816 ns/op  5778 B/op  56 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   92097  12883 ns/op  5780 B/op  56 allocs/op

BenchmarkDissectWithConversionMultipleValues-4 82034  14878 ns/op  5777 B/op  56 allocs/op
BenchmarkDissectWithConversionMultipleValues-4 81615  14511 ns/op  5781 B/op  56 allocs/op
BenchmarkDissectWithConversionMultipleValues-4 83312  14649 ns/op  5782 B/op  56 allocs/op
BenchmarkDissectWithConversionMultipleValues-4 79563  14699 ns/op  5777 B/op  56 allocs/op
BenchmarkDissectWithConversionMultipleValues-4 69480  16527 ns/op  5775 B/op  56 allocs/op

Proposed Change

Replace the multi-match regex call with a single-match call and index directly:

- m := suffixRE.FindAllStringSubmatch(rawKey, -1)
+ m := suffixRE.FindStringSubmatch(rawKey)
  if len(m) == 0 { ... }
- if m[0][3] != "" { ordinal, _ = strconv.Atoi(m[0][3]) }
+ if m[3] != "" { ordinal, _ = strconv.Atoi(m[3]) }
  ...
- return m[0][1], dataType, ordinal, length, greedy, nil
+ return m[1], dataType, ordinal, length, greedy, nil

File reference: libbeat/processors/dissect/field.go:337-359.

Results

After:

go test ./libbeat/processors/dissect -run '^$' -bench 'BenchmarkDissect(NoConversionMultipleValues|WithConversionMultipleValues)$' -benchmem -count=5

BenchmarkDissectNoConversionMultipleValues-4   102697 11245 ns/op  4324 B/op  50 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   102717 11443 ns/op  4329 B/op  50 allocs/op
BenchmarkDissectNoConversionMultipleValues-4    95758 11668 ns/op  4327 B/op  50 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   104931 11471 ns/op  4327 B/op  50 allocs/op
BenchmarkDissectNoConversionMultipleValues-4   102726 11642 ns/op  4331 B/op  50 allocs/op

BenchmarkDissectWithConversionMultipleValues-4  81697 13341 ns/op  4326 B/op  50 allocs/op
BenchmarkDissectWithConversionMultipleValues-4  88341 13258 ns/op  4323 B/op  50 allocs/op
BenchmarkDissectWithConversionMultipleValues-4  88832 13203 ns/op  4321 B/op  50 allocs/op
BenchmarkDissectWithConversionMultipleValues-4  89328 13416 ns/op  4324 B/op  50 allocs/op
BenchmarkDissectWithConversionMultipleValues-4  83425 13181 ns/op  4322 B/op  50 allocs/op

Improvement:

  • BenchmarkDissectNoConversionMultipleValues: 10.95% faster (avg 12907 -> 11493.8 ns/op)
  • BenchmarkDissectWithConversionMultipleValues: 11.78% faster (avg 15052.8 -> 13279.8 ns/op)
  • Memory: ~25.15% lower B/op (5778 -> 4325)
  • Allocations: 10.71% lower allocs/op (56 -> 50)

Verification

  • Ran relevant package tests: go test ./libbeat/processors/dissect -> ok.
  • Change is behavior-preserving (same regex/groups, only switching from all-matches to single-match for anchored pattern).

Evidence

  • Bench commands and outputs above.
  • Hot-path code location: libbeat/processors/dissect/field.go:337-359.
  • Candidate is distinct from /tmp/previous-findings.json entries (no existing dissect parser suffix extraction issue listed).

What is this? | From workflow: Performance Profiler

Give us feedback! React with πŸš€ if perfect, πŸ‘ if helpful, πŸ‘Ž if not.

  • expires on Mar 13, 2026, 2:29 PM UTC

Metadata

Metadata

Labels

needs_teamIndicates that the issue/PR needs a Team:* label

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions