Skip to content

Benchmarks

gogenfilter is designed for linters and static analysis tools where detection overhead must be negligible. The two-phase architecture (filename first, content only when needed) ensures most checks complete with zero I/O.

Benchmarked on Go 1.26, AMD Ryzen AI MAX+ 395. Results may vary by hardware.

Benchmarkns/opB/opallocs/op
Filter (enabled)69920
Filter (disabled)1.200
Filename detection (Phase 1)1400
Per-generator check (avg)~600
MatchPattern (doublestar **)7200
DetectReason (filename)3536324
DetectReason (content)6936805
Error construction200
errors.Is matching900

The primary API. Full end-to-end detection including filesystem access.

Filter/enabled 69 ns/op 92 B/op 0 allocs/op
Filter/disabled 1.2 ns/op 0 B/op 0 allocs/op

A disabled filter is essentially a branch prediction — 1.2 nanoseconds. An enabled filter with a known-generated file completes in ~69ns with zero heap allocations.

Phase 1: filename-based detection (zero I/O). This is the fast path — a single scan of the filename against the detector table. No file reads, no content parsing.

Filename phase 14 ns/op 0 B/op 0 allocs/op

This benchmarks the internal filename-only check. Results are exact-matched against known generated-file patterns (e.g., models.go, *.sql.go, _templ.go, .pb.go, wire_gen.go, _moq.go, _mock.go, mock_*.go).

Individual Is*Generated functions. Four of them (IsSQLCGenerated, IsTemplGenerated, IsGoEnumGenerated, IsProtobufGenerated) check both filename patterns and content markers. The remaining seven check content only.

IsGenericGenerated 5.0 ns/op 0 B/op 0 allocs/op
IsSQLCGenerated 5.9 ns/op 0 B/op 0 allocs/op
IsProtobufGenerated 7.0 ns/op 0 B/op 0 allocs/op

All under 7 nanoseconds with zero allocations.

Variadic detection across multiple filter options:

DetectReason/filename_only 353 ns/op 632 B/op 4 allocs/op
DetectReason/content_based 693 ns/op 680 B/op 5 allocs/op
DetectReason/not_filtered 614 ns/op 680 B/op 5 allocs/op

Higher cost than the per-generator checks because it iterates all enabled detectors and performs content matching. Still sub-microsecond.

Same as DetectReason but reads from an io.Reader:

DetectReasonReader/sqlc_filename 517 ns/op 1288 B/op 8 allocs/op
DetectReasonReader/not_filtered 812 ns/op 1272 B/op 9 allocs/op

Includes the cost of reading content from the reader.

MatchPattern with different glob patterns via doublestar:

MatchPattern/question 25 ns/op 0 B/op 0 allocs/op
MatchPattern/exact 40 ns/op 0 B/op 0 allocs/op
MatchPattern/wildcard 46 ns/op 0 B/op 0 allocs/op
MatchPattern/doublestar 72 ns/op 0 B/op 0 allocs/op
MatchPattern/no_match 77 ns/op 0 B/op 0 allocs/op

All zero-allocation. ** globs are the most expensive at ~72ns — still negligible.

Error construction and inspection:

NewSQLCConfigError 0.2 ns/op 0 B/op 0 allocs/op
NewProjectRootError 1.9 ns/op 0 B/op 0 allocs/op
ProjectRootErrorIs 7.9 ns/op 0 B/op 0 allocs/op
SQLCConfigErrorIs 8.9 ns/op 0 B/op 0 allocs/op
ProjectRootErrorError 229 ns/op 144 B/op 3 allocs/op
SQLCConfigErrorError 284 ns/op 176 B/op 5 allocs/op

Error construction and errors.Is matching are essentially free. Error() string formatting allocates but is only called when displaying errors.

Run the benchmarks yourself:

Terminal window
go test -bench=. -benchmem ./...

For stable results, run on a quiet system with CPU frequency scaling disabled.

Historical benchmark trends are tracked automatically on every push to master:

View Live Benchmark Dashboard

The dashboard shows:

  • Time-series charts for all 17 benchmarks
  • Commit-level granularity with tooltips showing commit messages
  • Automatic regression highlighting when performance degrades >150%

Results above are a point-in-time snapshot (Go 1.26, AMD Ryzen AI MAX+ 395). The dashboard provides continuous, hardware-consistent tracking from CI.