Host
Intel Core Ultra 9 285K · 24 cores
Platform
linux/amd64
Go
go1.27.0
CPython
python:3.14-slim
PyPy
pypy:3.11-slim
Runs / combo
7 + 2 warmup

Polymorphic AST eval

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

Runtime · median per inner-loop window

median of 7 runs

Native Gocompiled
2.06 ms0.06×
Pipitbytecode VM
31.9 msbaseline
CPython 3.14bytecode VM
51.9 ms1.63×
PyPy 7.3tracing JIT
86.2 ms2.70×
Ttengobytecode VM
119 ms3.73×
Sscriggobytecode VM
n/a
Mmvmbytecode VM
240 ms7.52×
YyaegiAST walker
1.10 s34.5×

Full statistics

RunnerNCompileRuntimeP95StddevRSSvs pipitStatus
Native Gocompiled7108 ms2.06 ms2.07 ms7.40 µs1.62 GiB0.06×OK
Pipitbytecode VM71.92 ms31.9 ms33.8 ms741 µs591 MiB1.00×OK
CPython 3.14bytecode VM7742 µs51.9 ms52.7 ms553 µsn/a1.63×OK
PyPy 7.3tracing JIT7555 µs86.2 ms100 ms6.82 msn/a2.70×OK
tengobytecode VM7344 µs119 ms125 ms3.01 ms1.69 GiB3.73×OK
scriggobytecode VM0n/an/an/an/an/an/aunsupported
mvmbytecode VM7620 µs240 ms256 ms6.40 ms1.69 GiB7.52×OK
yaegiAST walker7654 µs1.10 s1.13 s21.8 ms1.69 GiB34.5×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