Skip to content

Add bytecode VM for high-performance expression evaluation#35

Open
gryumov wants to merge 5 commits into
masterfrom
feature/bytecode-vm
Open

Add bytecode VM for high-performance expression evaluation#35
gryumov wants to merge 5 commits into
masterfrom
feature/bytecode-vm

Conversation

@gryumov
Copy link
Copy Markdown
Member

@gryumov gryumov commented May 4, 2026

Summary

  • New evaluation path: compile_expreval_compiled (bytecode VM) alongside existing parse_expreval_expr (tree walk)
  • Stack-based VM with zero heap allocations (pre-allocated stack)
  • 400–900x faster than tree walk, 63M+ evals/s throughput
  • 50–100 bytes per formula (vs 1–3 KiB for ExprNode tree)
  • Shared VarContext variable registry for index-based lookup across all formulas
  • BenchmarkTools-compatible benchmark suite (benchmark/benchmarks.jl)

New files

File Description
src/opcodes.jl Opcode constants with opcode() dispatch
src/context.jl VarContext shared variable registry
src/compiler.jl CompiledExpr + post-order compiler
src/vm.jl Stack-based bytecode interpreter
benchmark/benchmarks.jl PkgBenchmark-compatible SUITE

New exports

VarContext, compile_expr, eval_compiled

Version

1.0.1 → 1.1.0 (new feature, non-breaking)

Test plan

  • All 1717 tests pass (595 existing + 1122 new VM tests)
  • Zero allocations verified with @allocated
  • Correctness cross-check: 32 expressions produce same result via tree walk and VM
  • 1000-formula stress test
  • Run benchmark suite: julia --project=benchmark -e 'using BenchmarkTools; include("benchmark/benchmarks.jl"); tune!(SUITE); run(SUITE, verbose=true)'

🤖 Generated with Claude Code

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 4, 2026

Codecov Report

❌ Patch coverage is 98.44098% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.03%. Comparing base (1d483a7) to head (859c76e).

Files with missing lines Patch % Lines
src/context.jl 83.33% 3 Missing ⚠️
src/compiler.jl 98.21% 2 Missing ⚠️
src/eval.jl 94.11% 1 Missing ⚠️
src/vm.jl 99.61% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #35      +/-   ##
==========================================
+ Coverage   90.30%   97.03%   +6.73%     
==========================================
  Files           4        8       +4     
  Lines         330      777     +447     
==========================================
+ Hits          298      754     +456     
+ Misses         32       23       -9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

📘 A preview of the documentation will be here soon

@gryumov gryumov force-pushed the refactor/cleanup branch from 084505f to 990f016 Compare May 4, 2026 09:34
@gryumov gryumov force-pushed the feature/bytecode-vm branch from c16a7a4 to 9d33b42 Compare May 4, 2026 09:35
Base automatically changed from refactor/cleanup to master May 4, 2026 09:38
New evaluation path: compile_expr → eval_compiled (bytecode VM)
alongside the existing parse_expr → eval_expr (tree walk).

New files:
- src/opcodes.jl: opcode constants with dispatch pattern
- src/context.jl: VarContext shared variable registry
- src/compiler.jl: CompiledExpr + post-order compiler (ExprNode → bytecode)
- src/vm.jl: stack-based VM with zero-alloc evaluation
- benchmark/benchmarks.jl: BenchmarkTools SUITE (PkgBenchmark-compatible)

Key properties:
- 400-900x faster than tree walk for typical expressions
- Zero heap allocations with pre-allocated stack
- 50-100 bytes per formula (vs ~1-3 KiB for ExprNode tree)
- 63M+ evals/s throughput for bulk evaluation
- Shared VarContext allows single values vector across all formulas

New exports: VarContext, compile_expr, eval_compiled
Version bump: 1.0.1 → 1.1.0 (new feature, non-breaking)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gryumov gryumov force-pushed the feature/bytecode-vm branch from 9d33b42 to 456962b Compare May 4, 2026 09:39
gryumov and others added 4 commits May 4, 2026 17:26
Add tg (tangent), ctg (cotangent), and mean (N-ary average) functions
across all layers: eval, opcodes, compiler, and VM. The mean opcode
uses an inline argument count byte to support variable arity.

Refinements: eliminate heap allocations for tag-less variables (Nothing
instead of empty Dict), add constant pool overflow check in compiler,
broaden resolver to accept any callable (not just Function), and add
optional sizehint to VarContext constructor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These are pure math operations that belong in the VM level:
- tg(x) -> tan(x), ctg(x) -> cos(x)/sin(x)
- div(x,y), rem(x,y) for integer division and remainder
- mean(x...) for variadic average

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

3 participants