Host
Intel Core Ultra 9 285K · 24 cores
Platform
linux/amd64
Go
go1.26.0
CPython
python:3.13-slim
PyPy
pypy:3.10-slim
Runs / combo
10 + 2 warmup

Polymorphic AST eval

Interface / virtual-method dispatch through nine AST node types under heavy traversal load.

Compile time · median (cold)

median of 10 runs

Native Gocompiled
181 ms89.3×
Piko interpbytecode VM
2.03 msbaseline
CPython 3.13bytecode VM
620 µs0.31×
PyPy 7.3tracing JIT
482 µs0.24×
Ttengobytecode VM
373 µs0.18×
Sscriggobytecode VM
n/a
Mmvmbytecode VM
687 µs0.34×
YyaegiAST walker
702 µs0.35×

Full statistics

RunnerNCompileRuntimeP95StddevRSSvs pikoStatus
Native Gocompiled10181 ms2.11 ms2.13 ms12.0 µs69 MiB89.3×OK
Piko interpbytecode VM102.03 ms54.9 ms55.4 ms309 µs131 MiB1.00×OK
CPython 3.13bytecode VM10620 µs55.7 ms57.5 ms1.25 msn/a0.31×OK
PyPy 7.3tracing JIT10482 µs80.1 ms83.5 ms1.19 msn/a0.24×OK
tengobytecode VM10373 µs120 ms123 ms1.19 ms200 MiB0.18×OK
scriggobytecode VM0n/an/an/an/an/an/aunsupported
mvmbytecode VM10687 µs246 ms275 ms20.0 ms67 MiB0.34×OK
yaegiAST walker10702 µs1.40 s1.53 s49.4 ms71 MiB0.35×OK
Workload & symmetry rules

Workload

Build an expression tree from a deterministic LCG that mixes nine node kinds (Add, Sub, Mul, Mod, Const, Var, IfPos, Min, Max), each as a distinct struct/class satisfying a single-method contract: Node.Eval(env) uint32. Walk the tree repeatedly and accumulate the fold.

Symmetry rules

  • Real interface dispatch in Go (Eval(env) method on a Node interface) and class-based duck typing in Python.
  • No tagged-union switch shortcut; every Eval call must go through dynamic dispatch.

Why this benchmark exists

A direct measurement of the interpreter's interface / virtual-method dispatch path. Bench 05 is similar but uses a tagged-int switch; this one forces real virtual dispatch.

Source code