Architecture
How poly-bench is structured, how benchmarks flow, and how the runtime isolation works
How poly-bench is structured, how benchmarks flow, and how the runtime isolation works
poly-bench is built as a modular Rust workspace where each crate handles a specific responsibility. This architecture enables clean separation between parsing, validation, code generation, execution, and reporting.
.bench) are the source of truth for benchmark definitionsEvery benchmark flows through the same pipeline. Your .bench file is parsed into an AST, lowered to IR, used to generate language-specific code, executed in isolated runtimes, and finally reported.
| Component | Description |
|---|---|
| DSL | Lexer, parser, AST, formatter, and validator for .bench files |
| Polybench Runtime | Language-specific code generation (Go, TS, Rust, Python, C, C#, Zig) |
| Executor | Orchestrates benchmark runs, calibration, and measurement collection |
| Reporter | Console, markdown, JSON, and SVG chart output |
| LSP v2 | Language Server Protocol for editor support |
poly-bench-dsl to parse .bench files in a custom analysis tool.When you run poly-bench run benchmark.bench, the DSL parser tokenizes and parses your file into an AST. The validator checks for semantic errors like undefined fixtures or missing language blocks.
The AST is lowered to an Intermediate Representation that's fully resolved and normalized. This step resolves fixture references, merges configuration with defaults, and prepares data structures for code generation.
For each target language, poly-bench generates native benchmark code. The generated code includes imports, helper functions, fixture data, and a benchmark harness with timing code.
Each language runs in its own isolated subprocess. Runtime environments live in .polybench/runtime-env/ — each language has its own dependency directory for reproducible builds.