From daaca16e768f67390b335ca6fdb67d14da2e7db5 Mon Sep 17 00:00:00 2001 From: Ignacio Van Droogenbroeck Date: Mon, 2 Mar 2026 18:14:35 -0600 Subject: [PATCH] perf(encode): skip OmitEmpty slice allocation when no fields omitted Two-pass approach: first counts surviving fields, returns fs.List directly if all survive (zero allocs). Only allocates the filtered slice when fields are actually omitted. Common case for time-series data where most fields have values. --- types.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/types.go b/types.go index af1bedc..f46349b 100644 --- a/types.go +++ b/types.go @@ -159,8 +159,20 @@ func (fs *fields) OmitEmpty(e *Encoder, strct reflect.Value) []*field { return fs.List } - fields := make([]*field, 0, len(fs.List)) + // First pass: count surviving fields. If all survive, return the + // original slice without allocating a filtered copy. + n := 0 + for _, f := range fs.List { + if !f.Omit(e, strct) { + n++ + } + } + if n == len(fs.List) { + return fs.List + } + // Second pass: build the filtered slice only when necessary. + fields := make([]*field, 0, n) for _, f := range fs.List { if !f.Omit(e, strct) { fields = append(fields, f)