Standard Library
Built-in modules for Ethereum node spawning, chart generation, and mathematical constants
Built-in modules for Ethereum node spawning, chart generation, and mathematical constants
poly-bench includes a standard library with modules for common benchmarking tasks. Import them at the top of your .bench file with the use keyword before any suite or globalSetup blocks.
1use std::anvil # Ethereum node spawning2use std::charting # SVG chart generation3use std::constants # Mathematical constantsThe anvil module provides Ethereum node spawning for RPC benchmarks. It manages a local Anvil instance that all languages can connect to via a shared RPC URL.
anvil.spawnAnvil()Spawns a local Anvil instance. Call this inside a globalSetup block (file-level or suite-level).
1globalSetup {2 anvil.spawnAnvil() # Local node, no fork3 anvil.spawnAnvil(fork: "https://rpc.url") # Fork from an RPC endpoint4}| Parameter | Type | Required | Description |
|---|---|---|---|
fork | string | No | RPC URL to fork from (e.g. mainnet, Sepolia, Arbitrum) |
ANVIL_RPC_URLAfter spawnAnvil() is called, the local RPC endpoint is automatically injected into your setup code. The typical value is http://127.0.0.1:8545.
| Language | Access |
|---|---|
| TypeScript | ANVIL_RPC_URL — injected as a module-level constant in declare scope |
| Go | os.Getenv("ANVIL_RPC_URL") or pass directly as a string |
| Rust | std::env::var("ANVIL_RPC_URL").unwrap() |
anvil.stopAnvil()Stops the running Anvil instance. Not required — poly-bench cleans up the process automatically — but useful for explicit teardown in long-running suites.
1after {2 anvil.stopAnvil()3}1use std::anvil2
3globalSetup {4 anvil.spawnAnvil(fork: "https://eth.llamarpc.com")5}6
7suite evmBench {8 description: "EVM RPC benchmarks against a forked mainnet node"9 compare: true10 baseline: "go"11 mode: "auto"12 targetTime: 10000ms13 cvThreshold: 1014
15 setup go {16 import (17 "context"18 "github.com/ethereum/go-ethereum/ethclient"19 )20
21 declare {22 var client *ethclient.Client23 var ctx context.Context24 }25
26 init {27 ctx = context.Background()28 client, _ = ethclient.Dial(os.Getenv("ANVIL_RPC_URL"))29 }30
31 helpers {32 func getBlockNumber() uint64 {33 num, _ := client.BlockNumber(ctx)34 return num35 }36 }37 }38
39 setup ts {40 import {41 import { createPublicClient, http } from 'viem'42 import { mainnet } from 'viem/chains'43 }44
45 declare {46 let client: any47 }48
49 init {50 client = createPublicClient({51 chain: mainnet,52 transport: http(ANVIL_RPC_URL),53 })54 }55
56 helpers {57 async function getBlockNumber(): Promise<bigint> {58 return await client.getBlockNumber()59 }60 }61 }62
63 bench getBlockNumber {64 description: "Get the current block number via RPC"65 go: getBlockNumber()66 ts: await getBlockNumber()67 }68}The charting module generates SVG output from benchmark results. Chart directives must be called inside a suite-level after { } block and require use std::charting at the top of the file.
1use std::charting2
3suite example {4 # ... setup, fixtures, benchmarks ...5
6 after {7
8 charting.drawTable(title: "Results", output: "results-bar.svg")9 charting.drawSpeedupChart(10 title: "Speedup vs baseline",11 output: "results-speedup.svg",12 baselineBenchmark: "hashShort"13 )14 }15}output parameter controls the filename only. Files are written to the directory passed via --output, or to out/ when omitted.charting.drawTable(...)Generates an SVG summary table for benchmark results.
1charting.drawTable(2
3 title: "Performance Comparison",4 description: "Go vs TypeScript vs Rust",5 output: "results-table.svg",6 sortBy: "speedup",7 sortOrder: "desc",8 showStats: true,9 showGeoMean: true,10)drawTable Parameter ReferenceBasic
| Parameter | Type | Default | Description |
|---|---|---|---|
title | string | — | Chart title |
description | string | — | Subtitle / description text |
output | string | — | Output filename (e.g. "results.svg") |
width | integer | — | Chart width in pixels |
height | integer | — | Chart height in pixels |
width | integer | — | Output width in pixels |
height | integer | — | Output height in pixels |
Display Toggles
| Parameter | Type | Default | Description |
|---|---|---|---|
showStats | boolean | true | Show statistical summary panel |
showConfig | boolean | true | Show suite configuration panel |
showWinCounts | boolean | true | Show win-count badges per language |
showGeoMean | boolean | true | Show geometric mean bar |
compact | boolean | false | Compact layout with reduced padding |
Filtering
| Parameter | Type | Default | Description |
|---|---|---|---|
minSpeedup | float | — | Only include benchmarks where the fastest language is at least this much faster than the slowest |
filterWinner | string | "all" | Only include benchmarks won by this language ("go", "ts", "rust", or "all") |
includeBenchmarks | string[] | — | Whitelist of benchmark names to include |
excludeBenchmarks | string[] | — | Blacklist of benchmark names to exclude |
limit | integer | — | Maximum number of benchmarks to display |
Sorting
| Parameter | Type | Default | Description |
|---|---|---|---|
sortBy | string | — | Sort key: "speedup", "name", "time", "ops", "natural" |
sortOrder | string | — | "asc" or "desc" |
Typography + Values
| Parameter | Type | Default | Description |
|---|---|---|---|
titleFontSize | integer | — | Title font size in points |
subtitleFontSize | integer | — | Subtitle/description font size in points |
precision | integer | — | Decimal places for displayed values |
timeUnit | string | "auto" | Time unit: "auto", "ns", "us", "ms", "s" |
charting.drawSpeedupChart(...)Generates a speedup chart for benchmark comparison views.
1charting.drawSpeedupChart(2
3 title: "Speedup vs Go baseline",4 description: "How each benchmark compares to baseline",5 output: "results-speedup.svg",6 baselineBenchmark: "hashShort", # alias: baseline7 sortBy: "speedup",8 showGrid: true,9 gridOpacity: 0.15,10 legendPosition: "top-right"11)drawSpeedupChart Parameter Reference| Parameter | Type | Description |
|---|---|---|
title | string | Chart title |
description | string | Subtitle text |
output | string | Output filename |
width | integer | Chart width in pixels |
height | integer | Chart height in pixels |
baselineBenchmark / baseline | string | Benchmark used as baseline |
minSpeedup | float | Minimum speedup threshold for inclusion |
filterWinner | string | Filter by winning language |
includeBenchmarks | string[] | Whitelist of benchmark names |
excludeBenchmarks | string[] | Blacklist of benchmark names |
limit | integer | Maximum benchmarks to display |
sortBy | string | Sort key: "speedup", "name", "time", "ops", "natural" |
sortOrder | string | "asc" or "desc" |
showGrid | boolean | Show horizontal grid lines |
gridOpacity | float | Grid line opacity (0.0-1.0) |
titleFontSize | integer | Title font size |
subtitleFontSize | integer | Subtitle font size |
axisLabelFontSize | integer | Axis label font size |
tickLabelFontSize | integer | Tick label font size |
legendPosition | string | "top-left", "top-right", "bottom-left", "bottom-right", "hidden" |
theme | string | "dark" or "light" |
precision | integer | Decimal places for values |
timeUnit | string | Time unit for display |
You can generate any number of charts in a single after block. Each call produces a separate SVG file.
1use std::charting2
3suite comprehensive {4 # ... benchmarks ...5
6 after {7 # Grouped table for overall comparison8 charting.drawTable(9 title: "Overall Performance",10 output: "results-table.svg",11 sortBy: "speedup",12 sortOrder: "desc",13 showStats: true14 )15
16 # Speedup chart relative to a baseline benchmark17 charting.drawSpeedupChart(18 title: "Speedup vs baseline",19 output: "results-speedup.svg",20 baselineBenchmark: "hashShort",21 showGrid: true22 )23 }24}The constants module provides common mathematical constants for use in benchmark expressions and helper functions.
| Constant | Value | Description |
|---|---|---|
std_PI (Go/TS/Python), STD_PI (Rust) | 3.14159265358979... | Pi (π) |
std_E (Go/TS/Python), STD_E (Rust) | 2.71828182845904... | Euler's number (e) |
1use std::constants2
3suite mathBenchmarks {4 setup go {5 helpers {6 func circleArea(radius float64) float64 {7
8 return std_PI * radius * radius9 }10 }11 }12
13 setup ts {14 helpers {15 function circleArea(radius: number): number {16
17 return std_PI * radius * radius18 }19 }20 }21
22 setup rust {23 helpers {24 fn circle_area(radius: f64) -> f64 {25
26 STD_PI * radius * radius27 }28 }29 }30
31 bench area {32 go: circleArea(10.0)33 ts: circleArea(10.0)34 rust: circle_area(10.0)35 }36}std_PI/std_E, while Rust uses STD_PI/STD_E.| Module | Import | Key Functions / Constants |
|---|---|---|
std::anvil | use std::anvil | spawnAnvil(), stopAnvil(), ANVIL_RPC_URL |
std::charting | use std::charting | drawTable(), drawSpeedupChart() |
std::constants | use std::constants | std_PI/STD_PI, std_E/STD_E |
.bench file syntax