Performance Optimization
Techniques for optimizing the performance of your Starkbiter simulations and tests.
General Optimization
Parallel Execution
Run independent tests in parallel:
#![allow(unused)] fn main() { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn parallel_tests() { // Tests run concurrently } }
Batch Operations
Group operations to reduce overhead:
#![allow(unused)] fn main() { use tokio::try_join; // Instead of sequential let balance1 = env.get_balance(addr1).await?; let balance2 = env.get_balance(addr2).await?; let balance3 = env.get_balance(addr3).await?; // Use concurrent let (balance1, balance2, balance3) = try_join!( env.get_balance(addr1), env.get_balance(addr2), env.get_balance(addr3), )?; }
Reuse Environments
Reuse environments when possible:
#![allow(unused)] fn main() { // Expensive: create new environment for each test #[tokio::test] async fn test1() { let env = Environment::builder().build().await?; // ... } // Better: use fixtures with snapshots async fn test_fixture() -> (Environment, SnapshotId) { let env = Environment::builder().build().await?; // Setup common state let snapshot = env.snapshot().await?; (env, snapshot) } #[tokio::test] async fn test1() { let (env, snapshot) = test_fixture().await; // ... test ... env.restore(snapshot).await?; } }
Environment Optimization
Disable Unnecessary Features
#![allow(unused)] fn main() { let env = Environment::builder() .with_minimal_setup() // Skip unnecessary initialization .build() .await?; }
Control Block Production
#![allow(unused)] fn main() { // Manual block production for testing let env = Environment::builder() .with_block_time(0) // Manual mode .build() .await?; // Only mine when needed env.mine_block().await?; }
Agent Optimization
Efficient State Management
#![allow(unused)] fn main() { // Bad: Deep cloning on every execution struct InefficientBehavior { large_state: Vec<LargeData>, // Cloned frequently } // Good: Use references and Arc struct EfficientBehavior { large_state: Arc<Vec<LargeData>>, // Shared reference } }
Lazy Evaluation
#![allow(unused)] fn main() { struct LazyBehavior { cached_data: Option<ExpensiveData>, } impl Behavior for LazyBehavior { async fn execute(&mut self, world: &World) -> Result<()> { // Only compute when needed let data = match &self.cached_data { Some(d) => d, None => { let d = self.compute_expensive_data(world).await?; self.cached_data = Some(d); self.cached_data.as_ref().unwrap() } }; self.use_data(data).await?; Ok(()) } } }
Memory Management
Resource Cleanup
#![allow(unused)] fn main() { impl Drop for MyAgent { fn drop(&mut self) { // Clean up resources self.close_connections(); self.flush_caches(); } } }
Limit Cache Sizes
#![allow(unused)] fn main() { use lru::LruCache; struct CachedBehavior { cache: LruCache<Key, Value>, } impl CachedBehavior { fn new() -> Self { Self { cache: LruCache::new(1000.try_into().unwrap()), // Limit cache size } } } }
Profiling
Measure Performance
#![allow(unused)] fn main() { use std::time::Instant; async fn measure_performance<F, T>(name: &str, f: F) -> T where F: Future<Output = T>, { let start = Instant::now(); let result = f.await; let elapsed = start.elapsed(); println!("{} took {:?}", name, elapsed); result } // Usage let result = measure_performance("deploy_contract", async { deploy_contract(&account).await }).await?; }
Profile with tokio-console
// Add to Cargo.toml // [dependencies] // console-subscriber = "0.1" // In main #[tokio::main] async fn main() { console_subscriber::init(); // ... your code }
Benchmarking
Use Criterion for benchmarking:
#![allow(unused)] fn main() { use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn bench_contract_call(c: &mut Criterion) { let rt = tokio::runtime::Runtime::new().unwrap(); c.bench_function("contract_call", |b| { b.to_async(&rt).iter(|| async { let env = Environment::builder().build().await.unwrap(); let account = env.create_account().await.unwrap(); let contract = deploy_contract(&account).await.unwrap(); black_box(contract.call_method().await.unwrap()) }); }); } criterion_group!(benches, bench_contract_call); criterion_main!(benches); }
Next Steps
- Testing Strategies - Effective testing
- Simulation Techniques - Advanced simulations
- Anomaly Detection - Detecting issues