Setup Blocks
Per-language import, declare, init, and helpers
Setup blocks define language-specific imports, package-level declarations, one-time initialization, and helper functions. Each supported language has its own setup block, so you can write Go imports in one block and Rust imports in another.
1setup <lang> {2 import { ... }3 declare { ... }4 init { ... }5 helpers { ... }6}All four sub-sections are optional and can appear in any order. Supported languages: go, ts (or typescript), rust, python, c, csharp, zig.
| Sub-section | Purpose |
|---|---|
import | Language imports (packages, modules, crates) |
declare | Package/module-level variables, constants, types |
init | One-time setup before any benchmarks run |
helpers | Functions available to all bench blocks in the suite |
The import sub-section declares dependencies used by the setup and helpers. Use it to bring in packages, modules, or crates that your benchmark code needs.
1setup go {2 import (3 "context"4 "crypto/sha256"5 "github.com/ethereum/go-ethereum/ethclient"6 )7 helpers { ... }8}The declare sub-section holds package- or module-level variables, constants, or types. These are shared across all benchmarks in the suite.
If you want to access variables from your helper functions or benchmark code, they must be declared in the declare block. poly-bench uses the declare block to isolate and locate these variables when generating code. Variables defined only inside init or helpers without a corresponding declaration will not be found or properly isolated across the generated benchmark harness.
1setup go {2 declare {3 var client *ethclient.Client4 var ctx context.Context5 var mu sync.Mutex6 }7 init {8 ctx = context.Background()9 client, _ = ethclient.Dial(os.Getenv("ANVIL_RPC_URL"))10 }11 helpers { ... }12}The init sub-section runs once before any benchmarks in the suite. Use it to connect to services, load config, or initialize shared state that your helpers and benchmarks depend on.
1setup go {2 declare { var client *ethclient.Client }3 init {4 client, _ = ethclient.Dial(os.Getenv("ANVIL_RPC_URL"))5 }6 helpers {7 func getBlock() uint64 {8 num, _ := client.BlockNumber(context.Background())9 return num10 }11 }12}async init for asynchronous one-time setup. Use await freely inside it.The helpers sub-section defines functions that are available to all bench blocks in the suite. They receive fixture data and other arguments as parameters, and you can call them from your benchmark expressions.
1setup go {2 helpers {3 func keccak256(data []byte) [32]byte {4 return sha256.Sum256(data)5 }6 func bubbleSort(data []byte) []byte {7 n := len(data) / 48 arr := make([]int32, n)9 // ... sort logic ...10 return out11 }12 }13}1setup go {2 import (3 "encoding/binary"4 )5
6 declare {7 var counter int8 }9
10 init {11 counter = 012 }13
14 helpers {15 func bubbleGo(data []byte) []byte {16 n := len(data) / 417 arr := make([]int32, n)18 for i := 0; i < n; i++ {19 arr[i] = int32(binary.BigEndian.Uint32(data[i*4:(i+1)*4]))20 }21 for i := 0; i < n; i++ {22 for j := 0; j < n-1-i; j++ {23 if arr[j] > arr[j+1] {24 arr[j], arr[j+1] = arr[j+1], arr[j]25 }26 }27 }28 out := make([]byte, len(data))29 for i := 0; i < n; i++ {30 binary.BigEndian.PutUint32(out[i*4:(i+1)*4], uint32(arr[i]))31 }32 return out33 }34 }35}