poly-benchpoly-bench
Built in Rust · Open Source · MIT

Benchmark every
runtime.

Write benchmarks once in a simple DSL. Run them across Go, TypeScript, and Rust. Get unified, statistically sound results.

GoTypeScriptRust
keccak.bench
use std::charting
suite keccakBench {
description: "Keccak256 benchmark - Rust should win here"
warmup: 100ms
baseline: "go"
mode: "auto"
targetTime: 3000ms
after {
charting.drawSpeedupChart(
title: "Keccak256 Performance",
xlabel: "Time (ns)"
)
}
setup go {
import "golang.org/x/crypto/sha3"
helpers {
func keccak256Go(data []byte) []byte {
h := sha3.NewLegacyKeccak256()
h.Write(data)
return h.Sum(nil)
}
}
}
setup ts {
import {
import { keccak256 } from 'viem';
}
helpers {
function keccak256Ts(data: Uint8Array): Uint8Array {
return keccak256(data, 'bytes')
}
}
}
setup rust {
import {
use tiny_keccak::{Hasher, Keccak};
}
helpers {
fn keccak256_rust(data: &[u8]) -> [u8; 32] {
let mut hasher = Keccak::v256();
let mut output = [0u8; 32];
hasher.update(data);
hasher.finalize(&mut output);
output
}
}
}
fixture data {
hex: "68656c6c6f20776f726c64"
}
bench keccak256Bench {
go: keccak256Go(data)
ts: keccak256Ts(data)
rust: keccak256_rust(&data)
}
}
Terminal
$ curl -L https://install.evm-tooling.tools | bash

Why Poly Bench?

A multi-language benchmarking framework for fair cross-language comparisons.

No unified cross-language benchmarking — separate harnesses, different APIs, different methodologies

Fair comparisons are hard — different iteration counts, warmup strategies, and data inputs

Results are scattered — each language's output looks different, side-by-side comparisons are tedious

Unified Output

One run.
Every language.
Compared.

Run poly-bench run and get a statistical comparison across all three languages. Includes mean, standard deviation, ops/sec, and speedup ratios.

ConsoleMarkdownJSONSVG Charts
poly-bench run keccak.bench
Summary: keccak256Bench
─────────────────────────────────────────────
│ Lang │ Mean (ns/op) │ Std Dev │ Ops/s     │
├──────┼──────────────┼─────────┼───────────┤
│ rust │ 993          │ ± 1.8%  │ 1,006,752 │
│ go   │ 1,216        │ ± 2.1%  │ 822,714   │
│ ts   │ 15,667       │ ± 3.1%  │ 63,839    │

Comparison (baseline: go):
  rust: 1.22x faster
  ts:   12.88x slower
Architecture

How benchmarks flow

From .bench file to results — every benchmark follows the same five-stage pipeline.

01

Parse

Your .bench file → Lexer → AST → Semantic validation

02

Lower to IR

Resolve fixtures, merge config defaults, normalize imports

03

Generate

Emit native Go, TypeScript, and Rust benchmark code

04

Execute

Isolated subprocesses — no FFI, full native speed per language

05

Report

Console tables, markdown docs, JSON, SVG charts

Isolated Runtimes

Each language runs at full native speed

No interpretation, no FFI — isolated subprocesses with per-language memory tracking.

Go

Runtime
Plugin-based execution or subprocess
Memory
runtime.ReadMemStats

TypeScript

Runtime
Node.js subprocess
Memory
process.memoryUsage()

Rust

Runtime
Cargo build + subprocess
Memory
Custom allocator tracking
Key Features

Everything you need for rigorous benchmarking

poly-bench provides a complete toolkit — from DSL parsing to chart generation — built in Rust for speed and reliability.

Custom DSL

Clean, declarative syntax with language-specific setup blocks

Auto-calibration

Automatically adjusts iteration counts to reach target execution time

Memory Profiling

Track allocations across Go, TypeScript, and Rust

Portable Fixtures

Share hex-encoded test data across all language implementations

Chart Generation

SVG speedup charts and tables from results

LSP Support

Full editor integration with diagnostics, completions, and formatting

Modular Workspace

Rust workspace, 8 crates

Each crate handles a specific responsibility. Use them individually or together.

poly-bench-dsl

Lexer, parser, AST, formatter, validator

poly-bench-ir

Intermediate representation — normalized benchmark structures

poly-bench-runtime

Language-specific code generation and execution

poly-bench-executor

Orchestrates runs, calibration, measurements

poly-bench-reporter

Console, markdown, JSON, SVG output

poly-bench-lsp-v2

Language Server Protocol for editor support (v2)

poly-bench-stdlib

Standard library — anvil, charting, constants

poly-bench-project

Project init, dependency management, manifests

Statistics Done Right

No shortcuts on
measurement.

poly-bench includes proper statistical methodology so you can trust the numbers.

Warmup Removal

Discard initial iterations before timing

Multi-run

Run benchmarks N times for reliable stats

Outlier Detection

IQR-based outlier removal

Auto-calibration

Hit target execution time automatically

Ready to benchmark?

Install poly-bench and write your first .bench file in under a minute.

$ curl -sSL https://install.evm-tooling.tools | bash
Community

Get involved

poly-bench is open source and actively developed. Contributions welcome.