Skip to content

perf: reduce repeated eval STRING overhead (#1911) - #1926

Merged
fglock merged 7 commits into
masterfrom
feature/issue-1911-eval-string
Oct 29, 2026
Merged

fglock merged 7 commits into
masterfrom
feature/issue-1911-eval-string

Conversation

@fglock

@fglock fglock commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • Reduce repeated eval STRING overhead with lazy per-eval state and compiled interpreter-code caching keyed by source and runtime context.
  • Skip caching evals that emit compile-time warnings so warning handlers continue to run on every eval.
  • Add the Reduce the performance gap for repeated string eval #1911 work to the changelog.

The interpreter micro-benchmark reported in the branch drops repeated eval "1" from about 7–9 µs/eval to about 3 µs/eval; system Perl is about 1 µs/eval.

Part of #1911. The remaining performance gap still needs follow-up.

Validation

  • nice -n 19 timeout 1800 make — passed on the current-master-based code tree (d5cc6d1).
  • nice -n 19 timeout 600 make check-links — passed after the changelog update.

fglock and others added 5 commits October 29, 2026 15:29
JFR profiling of 1M `eval '1'` iterations revealed that per-eval
overhead is dominated by object allocation, not parsing or execution.
This commit targets the top allocation hotspots:

- Parser: replace IdentityHashMap sourceLineOffsets with int[] (416 samples)
- EmitterContext: lazy-init contextCache HashMap (97 samples)
- JavaClassInfo: lazy-init 4 pin/literal maps (135 samples)
- RuntimeCode + EvalStringHandler: skip HashMap deep copy of %^H when empty

The ScopedSymbolTable warningBitsString cache (plan item #3) was dropped
because getWarningBitsString() depends on external mutable state
(WarningFlags custom category registry) that cannot be reliably
invalidated from within ScopedSymbolTable.

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
async-profiler revealed two major CPU hotspots in the eval STRING path:

- InterpretedCode.shouldKeepRuntimeDeparseSource() called File.isFile()
  on every eval, causing a stat64 syscall (16% of CPU). Eval STRING
  source names like "(eval 42)" start with '(' and are never real files.
  Short-circuit on that prefix.

- WarningFlags.toWarningBitsString() iterated a ConcurrentHashMap (~40
  entries) twice per eval (~12.5% of CPU). Add a last-result cache keyed
  on the input BitSets and map sizes. The eval hot path re-computes the
  same warning state repeatedly.

Together these reduce eval '1' from 14.1 to 9.0 µs/eval (36% faster).

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When no warnings are explicitly disabled (the common case for eval '1'),
skip the ConcurrentHashMap iteration and return Collections.emptySet().

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cache compiled InterpretedCode objects in an LRU map keyed by eval
string + context (package, features, unicode, evalbytes). On cache hit,
skip parsing and compilation entirely — only withCapturedVars runs.

Evals that emit compile-time warnings (e.g. deprecated Unicode property
names) are excluded from caching via a thread-local flag in WarnDie, so
warning handlers always fire correctly on every eval.

Reduces eval "1" from ~7-9 µs/eval to ~3 µs/eval (system Perl: ~1 µs).

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the #1911 eval STRING improvements to the work-in-progress changelog.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <158243242+openai-codex[bot]@users.noreply.github.com>
fglock and others added 2 commits October 29, 2026 17:23
Restrict interpreter eval caching to context-free decimal integer literals so compile-time effects and dynamic symbol lookups run each time. Add regressions for attributes and ambiguous time dispatch.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <158243242+openai-codex[bot]@users.noreply.github.com>
@fglock
fglock merged commit f4f4962 into master Oct 29, 2026
2 checks 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