| Crates.io | mobench-sdk |
| lib.rs | mobench-sdk |
| version | 0.1.13 |
| created_at | 2026-01-13 09:25:52.009793+00 |
| updated_at | 2026-01-21 16:58:04.140716+00 |
| description | Mobile benchmarking SDK for Rust - run benchmarks on real devices |
| homepage | |
| repository | https://github.com/worldcoin/mobile-bench-rs |
| max_upload_size | |
| id | 2039790 |
| size | 328,028 |
Mobile benchmarking SDK for Rust - run benchmarks on real Android and iOS devices.
Transform your Rust project into a mobile benchmarking suite. This SDK provides everything you need to benchmark your Rust code on real mobile devices via BrowserStack or local emulators/simulators.
#[benchmark] macro: Mark functions for mobile benchmarkingmobench.toml for project settingsAdd mobench-sdk to your project:
[dependencies]
mobench-sdk = "0.1"
Mark functions to benchmark:
use mobench_sdk::benchmark;
#[benchmark]
fn fibonacci() {
let result = fib(30);
std::hint::black_box(result);
}
#[benchmark]
fn json_parsing() {
let data = serde_json::from_str::<MyStruct>(JSON_DATA).unwrap();
std::hint::black_box(data);
}
fn fib(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => fib(n - 1) + fib(n - 2),
}
}
Run programmatically:
use mobench_sdk::{run_benchmark, BenchSpec};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let spec = BenchSpec::new("fibonacci", 100, 10)?;
let report = run_benchmark(spec)?;
println!("Mean: {} ns", report.mean_ns());
println!("Median: {} ns", report.median_ns());
println!("Std dev: {} ns", report.stddev_ns());
Ok(())
}
Use the mobench CLI to scaffold your project:
cargo install mobench
cargo mobench init --target android # or ios, or both
This creates:
bench-mobile/ - FFI wrapper crateandroid/ or ios/ - Mobile app projectsbench-config.toml - Configuration fileuse mobench_sdk::benchmark;
#[benchmark]
fn my_benchmark() {
// Your code here
}
# Build to default output directory (target/mobench/)
cargo mobench build --target android
# Or with verbose output
cargo mobench build --target android --verbose
# Or preview what would be built
cargo mobench build --target android --dry-run
Local device workflow (builds artifacts and writes the run spec; launch the app manually):
cargo mobench run --target android --function my_benchmark
BrowserStack:
export BROWSERSTACK_USERNAME=your_username
export BROWSERSTACK_ACCESS_KEY=your_key
# Use --release for BrowserStack (smaller APK: ~133MB vs ~544MB debug)
cargo mobench run --target android --function my_benchmark \
--devices "Google Pixel 7-13.0" --release
examples/basic-benchmark: minimal SDK usage with #[benchmark]examples/ffi-benchmark: full UniFFI surface with run_benchmark and FFI typescrates/sample-fns: repository demo library used by Android/iOS test appsrun_benchmarkRun a registered benchmark by name:
use mobench_sdk::{run_benchmark, BenchSpec};
let spec = BenchSpec::new("my_function", 50, 5)?;
let report = run_benchmark(spec)?;
BenchmarkBuilderFluent API for building and running benchmarks:
use mobench_sdk::BenchmarkBuilder;
let report = BenchmarkBuilder::new("my_function")
.iterations(100)
.warmup(10)
.run()?;
BenchSpecBenchmark specification:
pub struct BenchSpec {
pub name: String,
pub iterations: u32,
pub warmup: u32,
}
RunnerReportBenchmark results with statistical analysis:
pub struct RunnerReport {
pub spec: BenchSpec,
pub samples: Vec<BenchSample>,
}
impl RunnerReport {
pub fn mean_ns(&self) -> f64;
pub fn median_ns(&self) -> u64;
pub fn min_ns(&self) -> u64;
pub fn max_ns(&self) -> u64;
pub fn stddev_ns(&self) -> f64;
pub fn percentile(&self, p: f64) -> u64;
}
use mobench_sdk::{InitConfig, Target, generate_project};
let config = InitConfig {
project_name: "my-benchmarks".to_string(),
output_dir: PathBuf::from("./bench-output"),
target: Target::Both, // Android + iOS
generate_examples: true,
};
let project_path = generate_project(&config)?;
use mobench_sdk::AndroidBuilder;
let builder = AndroidBuilder::new(PathBuf::from("."), "debug")?;
let apk = builder.build_apk()?;
println!("Built APK: {:?}", apk);
use mobench_sdk::IosBuilder;
let builder = IosBuilder::new(PathBuf::from("."), "release")?;
let xcframework = builder.build_xcframework()?;
println!("Built xcframework: {:?}", xcframework);
use mobench_sdk::benchmark;
use sha2::{Sha256, Digest};
use aes::Aes256;
#[benchmark]
fn sha256_1kb() {
let data = vec![0u8; 1024];
let hash = Sha256::digest(&data);
std::hint::black_box(hash);
}
#[benchmark]
fn aes256_encrypt() {
let key = [0u8; 32];
let cipher = Aes256::new(&key.into());
// ... encryption code
std::hint::black_box(cipher);
}
use mobench_sdk::benchmark;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct User {
name: String,
email: String,
age: u32,
}
const JSON_DATA: &str = r#"{"name":"Alice","email":"alice@example.com","age":30}"#;
#[benchmark]
fn parse_json_small() {
let user: User = serde_json::from_str(JSON_DATA).unwrap();
std::hint::black_box(user);
}
#[benchmark]
fn serialize_json_small() {
let user = User {
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
age: 30,
};
let json = serde_json::to_string(&user).unwrap();
std::hint::black_box(json);
}
use mobench_sdk::benchmark;
use std::collections::{HashMap, BTreeMap};
#[benchmark]
fn hashmap_insert_1000() {
let mut map = HashMap::new();
for i in 0..1000 {
map.insert(i, i * 2);
}
std::hint::black_box(map);
}
#[benchmark]
fn btreemap_insert_1000() {
let mut map = BTreeMap::new();
for i in 0..1000 {
map.insert(i, i * 2);
}
std::hint::black_box(map);
}
#[benchmark]inventory┌─────────────────────────────────────────┐
│ Your Rust Code + #[benchmark] │
└──────────────┬──────────────────────────┘
│
↓
┌─────────────────────────────────────────┐
│ mobench-sdk (Registry + Build Tools) │
└──────────────┬──────────────────────────┘
│
↓
┌─────────────────────────────────────────┐
│ UniFFI (FFI Bindings Generation) │
└──────────────┬──────────────────────────┘
│
┌───────┴───────┐
↓ ↓
┌─────────────┐ ┌───────────────────────┐
│ Android APK │ │ iOS xcframework / IPA │
└──────┬──────┘ └──────┬────────────────┘
│ │
└───────┬───────┘
↓
┌──────────────────────┐
│ Real Mobile Devices │
│ (BrowserStack/Local) │
└──────────────────────┘
mobench.toml (Project Configuration)mobench automatically loads mobench.toml from the current directory or parent directories:
[project]
crate = "bench-mobile"
library_name = "bench_mobile"
# output_dir = "target/mobench" # default
[android]
package = "com.example.bench"
min_sdk = 24
target_sdk = 34
[ios]
bundle_id = "com.example.bench"
deployment_target = "15.0"
[benchmarks]
default_function = "my_crate::my_benchmark"
default_iterations = 100
default_warmup = 10
bench-config.toml (Run Configuration)target = "android"
function = "sample_fns::fibonacci"
iterations = 100
warmup = 10
device_matrix = "device-matrix.yaml"
device_tags = ["default"] # optional; filter devices by tag
[browserstack]
app_automate_username = "${BROWSERSTACK_USERNAME}"
app_automate_access_key = "${BROWSERSTACK_ACCESS_KEY}"
project = "my-project-benchmarks"
[ios_xcuitest]
app = "target/mobench/ios/BenchRunner.ipa"
test_suite = "target/mobench/ios/BenchRunnerUITests.zip"
device-matrix.yamldevices:
- name: "Google Pixel 7-13.0"
os: "android"
os_version: "13.0"
tags: ["default", "pixel"]
- name: "iPhone 14-16"
os: "ios"
os_version: "16"
tags: ["default", "iphone"]
cargo-ndk: cargo install cargo-ndkaarch64-apple-ios, aarch64-apple-ios-simxcodegen: brew install xcodegenThis is the core SDK of the mobench ecosystem:
#[benchmark] proc macroLicensed under the MIT License. See LICENSE.md for details.
Copyright (c) 2026 World Foundation