Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Benchmarks

Performance characteristics of Keystone operations measured with Criterion.

Arithmetic Operations

OperationTime (ns)Throughput
Addition~8125M ops/sec
Subtraction~8125M ops/sec
Multiplication~8125M ops/sec
Division~3628M ops/sec
Remainder~4025M ops/sec

Rounding Operations

OperationTime (ns)
round_dp (2 places)~15
floor~12
ceil~12
trunc~10

Financial Calculations

OperationTime (ns)
simple_interest~25
compound_interest (12 periods, 5 years)~850
future_value (10 periods)~200
present_value (10 periods)~220
effective_annual_rate~180

Risk Metrics

OperationTime (ns)
health_factor~45
liquidation_price~50
collateral_ratio~40
max_borrowable~55

precision-core vs rust_decimal

Measured with Criterion.rs on identical hardware. precision-core wraps rust_decimal with checked arithmetic, overflow detection, and formal verification boundaries.

Operationprecision-core (ns)rust_decimal (ns)Overhead
Addition7.37.0~4%
Subtraction8.07.5~7%
Multiplication8.77.7~13%
Division32.832.4~1%
mul_div (compound)22.720.4~11%
Compound interest (12×)127.0105.0~21%
Health factor (mul+div)23.421.2~10%
Swap output (3 ops)73.869.9~6%
Large value mul16.716.1~4%
Large value div70.769.4~2%

The wrapper overhead ranges from 1-13% for individual operations and 6-21% for compound operations. This cost buys:

  • Checked arithmetic that returns Option instead of panicking
  • Formal verification via Kani proof harnesses
  • Consistent error types (ArithmeticError)
  • DeFi-specific operations (health factor, swap math)

Run the comparison benchmark:

cargo bench --package precision-core --bench comparison

Running Benchmarks

cd keystone
cargo bench

Specific Benchmark

cargo bench --bench arithmetic
cargo bench --bench financial
cargo bench --bench risk

With Baseline Comparison

# Save baseline
cargo bench -- --save-baseline main

# Compare to baseline
cargo bench -- --baseline main

Benchmark Code

Located in crates/precision-core/benches/:

#![allow(unused)]
fn main() {
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use precision_core::Decimal;

fn bench_addition(c: &mut Criterion) {
    let a = Decimal::from(12345i64);
    let b = Decimal::from(67890i64);

    c.bench_function("decimal_add", |bencher| {
        bencher.iter(|| black_box(a).checked_add(black_box(b)))
    });
}

criterion_group!(benches, bench_addition);
criterion_main!(benches);
}

Stylus Gas Benchmarks

Keystone Stylus contracts deployed on Arbitrum One.

Deployed Contracts

ContractAddressSize
stylus-lending0x4dff9348275ac3c24e2d3abf54af61d3ebee158512.2 KB
stylus-amm0x9615cc2f65d8bbe4cdc80343db75a6ec32da93cd16.9 KB
stylus-vault0xdaf8f1a5f8025210f07665d4ccf2d2c0622a41fa14.4 KB

Measured Gas Usage (Arbitrum One)

ContractFunctionGas
stylus-lendingcalculateHealthFactor59,853
stylus-lendingisLiquidatable59,851
stylus-ammcalculateSpotPrice60,026
stylus-ammcalculateSwapOutput62,651
stylus-ammcalculateLiquidityMint61,142
stylus-vaultcalculateSharePrice59,082
stylus-vaultcalculateSharesForDeposit59,396
stylus-vaultcalculateAssetsForRedeem59,452
stylus-vaultcalculateCompoundYield (30 periods)59,904
stylus-vaultcalculateApyFromApr (365 compounds)75,656
stylus-vaultcalculatePerformanceFee60,799
stylus-vaultcalculateManagementFee61,122

Gas Comparison: Stylus vs Solidity (Measured)

Solidity benchmark contract: 0x41d4f095Da18Fd25c28CDbE0532a6fb730bbB9CF

OperationStylus (gas)Solidity (gas)Winner
Share price (1 div)58,74222,606Solidity 62% cheaper
Shares for deposit (2 ops)59,00522,898Solidity 61% cheaper
Compound yield (30 loops)59,51333,205Solidity 44% cheaper
APY from APR (365 loops)75,316148,881Stylus 49% cheaper

Key Insight

Simple arithmetic: Solidity wins due to lower base overhead.

Loop-heavy computation: Stylus wins significantly. As iterations increase, Stylus becomes more efficient because WASM opcodes cost ~100x less than EVM opcodes.

When to Use Stylus

Use Keystone + Stylus when:

  • Calculations involve many iterations (compound interest, Monte Carlo)
  • 28-digit precision is required (vs Solidity’s 18-digit practical limit)
  • Cross-platform determinism matters (same results everywhere)

Use Solidity when:

  • Simple arithmetic only
  • Gas optimization is critical for single operations
  • Existing Solidity codebase

Break-Even Analysis

Based on measured data, Stylus becomes cheaper at approximately 100+ loop iterations per call.

Why Stylus is Cheaper

  1. WASM Execution: WASM opcodes cost ~1/100th of EVM opcodes
  2. No Storage Overhead: Pure computation functions avoid SLOAD/SSTORE
  3. Efficient Loops: Iteration-heavy calculations (compound interest) benefit most
  4. Native Integer Ops: 128-bit arithmetic is native in WASM

Running Gas Benchmarks

Install Foundry:

curl -L https://foundry.paradigm.xyz | bash
foundryup

Estimate gas for a call:

cast estimate 0x4dff9348275ac3c24e2d3abf54af61d3ebee1585 \
  "calculateHealthFactor(uint256,uint256)(uint256)" \
  10000000000000000000000 5000000000000000000000 \
  --rpc-url https://arb1.arbitrum.io/rpc

Activation Costs

One-time costs paid at deployment:

ContractActivation Fee
stylus-lending0.000090 ETH
stylus-amm0.000103 ETH
stylus-vault0.000099 ETH

After activation, calls use standard Arbitrum gas pricing.


WASM Performance

WASM operations include JS-WASM boundary overhead:

OperationNative (ns)WASM (ns)Overhead
Addition8~50~6x
Division36~100~3x
compound_interest850~1200~1.4x

WASM Binary Size

BuildSize
Debug~450 KB
Release~97 KB
Release + wasm-opt~85 KB

Optimization Settings

From Cargo.toml:

[profile.release]
opt-level = "z"      # Optimize for size
lto = "fat"          # Full link-time optimization
codegen-units = 1    # Better optimization
panic = "abort"      # Smaller binary
strip = true         # Remove symbols
overflow-checks = true  # Keep overflow checking

Memory Usage

TypeSize
Decimal16 bytes
RoundingMode1 byte
ArithmeticError1 byte

Stack-only allocation for all operations.

Comparison with Alternatives

vs JavaScript Number

// JavaScript floating-point
0.1 + 0.2  // 0.30000000000000004

// Keystone
keystone.add("0.1", "0.2")  // "0.3"

Keystone is slower but guarantees correctness for financial calculations.

vs BigInt

JavaScript BigInt handles integers only. Keystone provides:

  • Decimal precision up to 28 digits
  • Native rounding modes
  • Financial functions

vs decimal.js

Similar precision, but Keystone provides:

  • Deterministic cross-platform results
  • Smaller WASM bundle
  • ZK-proof compatibility
  • Rust native performance

Profiling

CPU Profiling

cargo bench --bench arithmetic -- --profile-time 10

Memory Profiling

cargo bench --bench arithmetic -- --plotting-backend disabled

CI Benchmarks

Benchmarks run on every PR to detect regressions:

- name: Run benchmarks
  run: cargo bench -- --noplot

- name: Compare with main
  run: |
    cargo bench -- --save-baseline pr
    git checkout main
    cargo bench -- --baseline pr