Skip to content

perf: reduce compiler allocation overhead and close the JIT gap - #515

Merged
toakleaf merged 1 commit into
masterfrom
codex/performance-jit-parity
Jul 15, 2026
Merged

toakleaf merged 1 commit into
masterfrom
codex/performance-jit-parity

Conversation

@toakleaf

Copy link
Copy Markdown
Owner

Summary

  • remove ineffective sync.Pool lookups from hot AST constructors and embed base nodes in high-volume AST types
  • share immutable built-in function definitions while preserving per-compilation child registries
  • replace the hottest parser regex probes with exact byte scanners
  • replace recursive visitor pool traffic with visitor-local storage
  • reuse the immutable default() guard sentinel
  • add a benchmark for the exported Compile API and update the benchmark documentation
  • document GOGC=200 as an opt-in throughput setting rather than changing the process-wide runtime from the library

Performance

Measured on Apple M1 Max, Go 1.24.5, Node.js 24.4.1, 212 benchmark files:

Benchmark Before / JS After / Go
Go BenchmarkLargeSuite median 143.10 ms 115.17 ms
Go allocations per build ~1.321M ~1.147M
Fresh-process full build JS 207.08 ms Go 117.46 ms
Cold per-file average JS 799.19 µs Go 505.55 µs
Warm isolated-file average JS 402.75 µs Go 476.68 µs
Warm aggregate median, default GC JS 102.57 ms Go 112.07 ms
Warm aggregate median, GOGC=200 JS 102.57 ms Go 96.78 ms

The retained code changes improve the core Go suite by about 19.5%. Realistic fresh-process builds are 1.8x faster than Less.js. Peak-JIT isolated-file performance remains about 18% ahead of default Go, while GOGC=200 moves the aggregate warmed Go suite slightly ahead with a larger heap target.

GC trace sampling over 15 builds:

Setting GC cycles Maximum observed heap goal
GOGC=100 553 10 MB
GOGC=200 193 15 MB
GOGC=400 76 27 MB

Investigation notes

Several ideas were measured and reverted rather than included:

  • explicit parse-tree release reduced allocations but slowed the suite by about 5.5%
  • a generic no-capture regexp fast path regressed performance
  • direct Unit allocation and combinator trimming changes had no reproducible effect

Validation

  • go test ./...
  • go test -race ./less -run='TestCompile|TestFactory|TestIntegrationSuite/main/functions|TestFunctionRegistry' -count=1
  • go run scripts/test.go integration — repository baseline 316/317, one existing compile failure, zero output differences
  • node scripts/bench-compare.js
  • node scripts/bench-compare-suite.js

@toakleaf
toakleaf merged commit d482f8d into master Jul 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant