Cross-language benchmarks where every runtime is measured inside one dev container,
so hardware, kernel, VM and toolchain versions are held constant. Each benchmark lives in
its own folder and shares the container image at .devcontainer/.
The goal is not to rank languages. It is to make narrow, well-understood workloads measurable under identical conditions, and to be explicit about what each result does and does not tell you. Every benchmark README carries its own caveats section — read it before quoting a number.
| Benchmark | What it measures | Runtimes |
|---|---|---|
naive-fib/ |
Unmemoised recursive fib(n) — function call overhead and how far each compiler will restructure recursion |
17 |
One image provides every toolchain used by any benchmark:
| AOT | gcc, clang, Rust, Go, GraalVM native-image, .NET NativeAOT |
| JIT | .NET 10 (C#/F#), Temurin 25 (HotSpot C2), Julia, Node/V8, LuaJIT, PyPy |
| Interpreted | Lua 5.1, Lua 5.4, CPython |
Open the repo in VS Code and run Dev Containers: Reopen in Container, then follow the individual benchmark's README.
To build and run it directly instead:
docker build -t polybench .devcontainer
docker run --rm -v "$PWD:/w" -w /w polybench bash naive-fib/bench/run.shPodman users:
.devcontainer/devcontainer.jsonsets--userns=keep-id, which is a Podman flag — Docker rejects it, so remove thatrunArgsentry if you use Docker. Point VS Code at Podman with"dev.containers.dockerPath": "podman".
The image pulls the .NET SDK, GraalVM, Temurin, Rust, Go, Julia and Node. It is large (~8 GB) and the first build takes a while.
- Create a folder with a
bench/subdirectory and aREADME.mdcovering results, methodology and caveats. - Add any missing toolchain to
.devcontainer/Dockerfile— the image is shared, so other benchmarks get it too. - Add a row to the table above.
Keep the measurement protocol consistent across benchmarks: take sizing parameters from argv so nothing can be constant-folded, run an untimed warm-up phase before timing, and report best alongside mean.
MIT — see LICENSE.