Skip to content

Eliminate lazy initialization overhead from interpreter hot paths (~8% faster)#2346

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:prepare-improvement
Mar 22, 2026
Merged

Eliminate lazy initialization overhead from interpreter hot paths (~8% faster)#2346
lahma merged 1 commit into
sebastienros:mainfrom
lahma:prepare-improvement

Conversation

@lahma

@lahma lahma commented Mar 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Remove _initialized bool field and branch from JintStatement.Execute() — the interpreter's hottest path — by moving all Initialize() work into constructors
  • Apply the same pattern to 12 expression types (JintBinaryExpression, JintCallExpression, JintMemberExpression, etc.)
  • Remove EvaluationContext dependency from ExpressionCache.Initialize() so call/new/array/object expression caches can also be built eagerly
  • Move JintStatementList and JintSwitchBlock array construction to constructors
  • Net result: 36 files changed, 212 insertions, 468 deletions (simpler code that's also faster)

Rationale

Every JintStatement.Execute() call checked if (!_initialized) on every invocation — not just the first. In tight loops this branch accumulates measurably. Since none of the Initialize() methods actually used the EvaluationContext parameter (they only called JintExpression.Build(), JintStatement.Build(), and ProbablyBlockStatement()), moving the work to constructors is safe and eliminates the per-execution branch.

Benchmark results (SunSpider, 26 tests, lower is better)

Phase Total vs Baseline
Baseline (main) 2,693 ms
+ Statement _initialized elimination 2,516 ms -6.6%
+ Expression _initialized elimination 2,490 ms -7.6%
+ StatementList/SwitchBlock init 2,474 ms -8.2%

Biggest individual improvements: bitops-nsieve-bits -10%, date-format-xparb -10%, math-cordic -8.9%, crypto-aes -7.8%, crypto-sha1 -7.1%

Test plan

  • Jint.Tests: 2,764 passed, 0 failed
  • Test262: 95,798 passed, 0 failed, no regressions
  • SunSpider benchmark: ~8% improvement
  • Dromaeo benchmark: no regressions
  • Stopwatch benchmark: no regressions

🤖 Generated with Claude Code

…% faster)

Remove `_initialized` bool check from every statement execution and expression
evaluation by moving initialization work into constructors. Previously, each
`JintStatement.Execute()` call checked `if (!_initialized)` on every invocation,
adding a branch to the interpreter's hottest path. Since none of the Initialize()
methods actually needed the EvaluationContext, moving them to constructors is safe.

Changes:
- Remove `_initialized` field and `Initialize()` virtual method from JintStatement base
- Move initialization to constructors in all 17 statement subclasses
- Move initialization to constructors in 12 expression types (JintBinaryExpression,
  JintCallExpression, JintMemberExpression, JintUpdateExpression, etc.)
- Remove EvaluationContext dependency from ExpressionCache.Initialize()
- Move JintStatementList Pair[] construction to constructor
- Move JintSwitchBlock case array construction to constructor
- Handle debug mode FastResolve check at execution time instead of init time

SunSpider benchmark: 2,693ms → 2,474ms (-8.2%, 26 tests)
Test262: 0 failures, 95,798 passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lahma
lahma enabled auto-merge (squash) March 22, 2026 13:10
@lahma
lahma merged commit c88892c into sebastienros:main Mar 22, 2026
4 checks passed
@lahma
lahma deleted the prepare-improvement branch March 22, 2026 13:19
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