From f5774b580b32cf19eaf92892f83afe10573659b9 Mon Sep 17 00:00:00 2001 From: Robert Sayre Date: Fri, 23 Jan 2026 12:59:51 -0800 Subject: [PATCH] Pool result buffer in nfaBuffers to reduce allocations This change adds a resultBuf field to nfaBuffers and a matchesInto() method to matchSet. Instead of allocating a new slice for each match result, we reuse the pooled buffer by appending matches to it. The buffer is reset to length 0 before each use while preserving capacity. --- core_matcher.go | 2 +- match_set.go | 9 +++++++++ nfa.go | 10 ++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/core_matcher.go b/core_matcher.go index 142ad4a..891c00b 100644 --- a/core_matcher.go +++ b/core_matcher.go @@ -177,7 +177,7 @@ func (m *coreMatcher) matchesForFields(fields []Field, bufs *nfaBuffers) ([]X, e for i := 0; i < len(fields); i++ { tryToMatch(fields, i, cmFields.state, matches, bufs) } - return matches.matches(), nil + return matches.matchesInto(bufs.resultBuf[:0]), nil } // tryToMatch tries to match the field at fields[index] to the provided state. If it does match and generate diff --git a/match_set.go b/match_set.go index 1da255e..712d684 100644 --- a/match_set.go +++ b/match_set.go @@ -46,3 +46,12 @@ func (m *matchSet) matches() []X { } return matches } + +// matchesInto appends matches to the provided buffer and returns it. +// This avoids allocating a new slice for the result. +func (m *matchSet) matchesInto(buf []X) []X { + for x := range m.set { + buf = append(buf, x) + } + return buf +} diff --git a/nfa.go b/nfa.go index 1bdca1d..af8ce9d 100644 --- a/nfa.go +++ b/nfa.go @@ -74,14 +74,16 @@ type nfaBuffers struct { buf1, buf2 []*faState eClosure *epsilonClosure matches *matchSet + resultBuf []X } func newNfaBuffers() *nfaBuffers { return &nfaBuffers{ - buf1: make([]*faState, 0, 16), - buf2: make([]*faState, 0, 16), - eClosure: newEpsilonClosure(), - matches: newMatchSet(), + buf1: make([]*faState, 0, 16), + buf2: make([]*faState, 0, 16), + eClosure: newEpsilonClosure(), + matches: newMatchSet(), + resultBuf: make([]X, 0, 16), } }