eth.zig

Benchmarks

eth.zig vs alloy.rs -- head-to-head performance comparison across 26 Ethereum operations.

eth.zig vs Rust -- a head-to-head performance comparison of eth.zig and alloy.rs across 26 core Ethereum operations.

Score: eth.zig wins 18/26 | alloy.rs wins 5/26 | tied 3/26

Run date: 2026-06-10 on Apple Silicon (aarch64-macos) with ReleaseFast (Zig) vs --release (Cargo). alloy crate versions: alloy-primitives 1.6.0, alloy-sol-types 1.6.0, alloy-dyn-abi 1.6.0, alloy-consensus 2.0.5, alloy-signer 2.0.5, alloy-rlp 0.3.15. Custom criterion-style harness with 0.5s warmup, calibrated batch sizes, and 2s measurement window. Both mulDiv benchmarks use true 512-bit intermediate arithmetic.

Full Results

Benchmarketh.zigalloy.rsWinner
keccak256_empty261 ns310 nszig 1.19x
keccak256_32b263 ns319 nszig 1.21x
keccak256_256b534 ns532 nsrs 1.00x
keccak256_1kb2,073 ns2,039 nsrs 1.02x
keccak256_4kb7,732 ns7,838 nszig 1.01x
secp256k1_sign22,033 ns51,490 nszig 2.34x
secp256k1_sign_recover52,095 ns220,150 nszig 4.23x
address_derivation265 ns328 nszig 1.24x
address_from_hex17 ns11 nsrs 1.55x
checksum_address304 ns341 nszig 1.12x
abi_encode_transfer24 ns47 nszig 1.96x
abi_encode_static25 ns97 nszig 3.88x
abi_encode_dynamic171 ns337 nszig 1.97x
abi_decode_uint25614 ns51 nszig 3.64x
abi_decode_dynamic32 ns269 nszig 8.41x
rlp_encode_eip1559_tx3 ns73 nszig 24.33x
rlp_decode_u2567 ns7 nstie
u256_add4 ns4 nstie
u256_mul5 ns10 nszig 2.00x
u256_div7 ns24 nszig 3.43x
u256_uniswapv2_amount_out24 ns24 nstie
u256_mulDiv17 ns31 nszig 1.82x
u256_uniswapv4_swap45 ns42 nsrs 1.07x
hex_encode_32b26 ns24 nsrs 1.08x
hex_decode_32b24 ns28 nszig 1.17x
tx_hash_eip1559271 ns361 nszig 1.33x

Score Summary

Count
eth.zig wins18
alloy.rs wins5
Tied3

Key Optimizations

OptimizationImpact
bitcoin-core/secp256k1 C backend (vendored)secp256k1_sign: 2.34x faster than alloy; sign_recover: 4.23x faster
Lane-complementing Keccak-f[1600] (XKCP opt64)keccak256_32b: 1.21x faster than alloy (larger inputs are now within ~2% of alloy 1.6)
Streamlined mulDiv with native u128 divisionmulDiv: 1.82x faster than alloy (17ns vs 31ns)
mulWide + divWide (Knuth D for 512-bit)Replaces 256-iteration binary long division with ~4-iteration Knuth D
Half-word division (div128by64)u256_div: 7ns, 3.43x faster than alloy
FixedBufferAllocator in benchmarksEliminates allocator overhead for ABI/RLP/TX benchmarks
Vendored bitcoin-core/secp256k1 + XKCP keccakBest-in-class C backends compiled by zig build
Custom criterion-style harnessAccurate timing in the sub-25ns regime; zbench had ~25ns floor on macOS

Where alloy.rs Wins

BenchmarkGapRoot Cause
address_from_hex1.55xalloy uses SIMD hex parsing; eth.zig uses scalar loop
hex_encode_32b1.08xalloy's const-hex crate uses vectorized encoding
u256_uniswapv4_swap1.07xruint's U512 widening mul/div edges out eth.zig on this path
keccak256_256b1.00xwithin measurement noise (~0.4%)
keccak256_1kb1.02xwithin measurement noise (~2%)

Reproducing

# Full comparison (requires Zig, Rust, Python 3)
bash bench/compare.sh

# eth.zig benchmarks only
zig build bench

# alloy benchmarks only
(cd bench/alloy-bench && cargo bench --bench eth_comparison)

On this page