Expand description
§mobench-sdk
Mobile benchmarking SDK for Rust. It provides runtime timing, benchmark registration, Android/iOS builders, generated runner templates, UniFFI compatibility, native JSON C ABI exports, and local profiling helpers.
§Install
[dependencies]
mobench-sdk = "0.1.42"
inventory = "0.3"
[lib]
crate-type = ["cdylib", "staticlib", "lib"]Generated runners use ffi_backend = "uniffi" by default. Set
ffi_backend = "native-c-abi" in mobench.toml to use the direct
mobench JSON C ABI path and export it from the benchmark crate with
mobench_sdk::export_native_c_abi!().
For complete integration instructions, see https://github.com/worldcoin/mobile-bench-rs/blob/main/docs/guides/sdk-integration.md.
[dependencies]
mobench-sdk = "0.1.42"
inventory = "0.3" # Required for benchmark registration§2. Define Benchmarks
Use the #[benchmark] attribute to mark functions for benchmarking:
use mobench_sdk::benchmark;
#[benchmark]
fn my_expensive_operation() {
let result = expensive_computation();
std::hint::black_box(result); // Prevent optimization
}
#[benchmark]
fn another_benchmark() {
for i in 0..1000 {
std::hint::black_box(i * i);
}
}§3. Build and Run
Use the mobench CLI to build and run benchmarks:
# Install the CLI
cargo install mobench
# Build for Android (outputs to target/mobench/)
cargo mobench build --target android
# Build for iOS
cargo mobench build --target ios
# Run on BrowserStack (use --release for smaller APK uploads)
cargo mobench run --target android --function my_expensive_operation \
--iterations 100 --warmup 10 --devices "Google Pixel 7-13.0" --release
# Or capture a local native profile
cargo mobench profile run --target android --provider local \
--backend android-native --function my_expensive_operation§Architecture
The SDK consists of several components:
| Module | Description |
|---|---|
timing | Core timing infrastructure (always available) |
registry | Runtime discovery of #[benchmark] functions (requires registry or full feature) |
runner | Benchmark execution engine (requires registry or full feature) |
builders | Android and iOS build automation (requires builders or full feature) |
codegen | Mobile app template generation (requires codegen, builders, or full feature) |
types | Common types and error definitions |
§Crate Ecosystem
The mobench ecosystem consists of three published crates:
mobench-sdk(this crate) - Core SDK library with timing harness and build automationmobench- CLI tool for building and running benchmarksmobench-macros-#[benchmark]proc macro
Note: The mobench-runner crate has been consolidated into this crate as the timing module.
§Feature Flags
| Feature | Default | Description |
|---|---|---|
full | Yes | Full SDK with build automation, templates, and registry |
registry | No | Benchmark macro, inventory registry, and runtime execution without build tooling |
builders | No | Android/iOS build automation; enables codegen |
codegen | No | Project and mobile app template generation |
runner-only | No | Minimal timing-only mode for mobile binaries |
For mobile binaries where binary size matters, use runner-only:
[dependencies]
mobench-sdk = { version = "0.1.42", default-features = false, features = ["runner-only"] }§Programmatic Usage
You can also use the SDK programmatically:
§Using the Benchmark Builder Pattern
Requires the registry or full feature.
use mobench_sdk::BenchmarkBuilder;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let report = BenchmarkBuilder::new("my_benchmark")
.iterations(100)
.warmup(10)
.run()?;
println!("Mean: {} ns", report.mean_ns());
Ok(())
}§Using BenchSpec With Registry Dispatch
Requires the registry or full feature. With runner-only, use
run_closure or timing::run_closure for manual dispatch instead.
use mobench_sdk::{BenchSpec, run_benchmark};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let spec = BenchSpec::new("my_benchmark", 50, 5)?;
let report = run_benchmark(spec)?;
println!("Collected {} samples", report.samples.len());
Ok(())
}§Discovering Benchmarks
Requires the registry or full feature.
use mobench_sdk::{discover_benchmarks, list_benchmark_names};
fn main() {
// Get all registered benchmark names
let names = list_benchmark_names();
for name in names {
println!("Found benchmark: {}", name);
}
// Get full benchmark function info
let benchmarks = discover_benchmarks();
for bench in benchmarks {
println!("Benchmark: {}", bench.name);
}
}§Building Mobile Apps
The SDK includes builders for automating mobile app creation:
§Android Builder
use mobench_sdk::builders::AndroidBuilder;
use mobench_sdk::{BuildConfig, BuildProfile, Target};
let builder = AndroidBuilder::new(".", "my-bench-crate")
.verbose(true)
.output_dir("target/mobench"); // Default
let config = BuildConfig {
target: Target::Android,
profile: BuildProfile::Release,
incremental: true,
};
let result = builder.build(&config)?;
println!("APK built at: {:?}", result.app_path);§iOS Builder
use mobench_sdk::builders::{IosBuilder, SigningMethod};
use mobench_sdk::{BuildConfig, BuildProfile, Target};
let builder = IosBuilder::new(".", "my-bench-crate")
.verbose(true);
let config = BuildConfig {
target: Target::Ios,
profile: BuildProfile::Release,
incremental: true,
};
let result = builder.build(&config)?;
println!("xcframework built at: {:?}", result.app_path);
// Package IPA for distribution
let ipa_path = builder.package_ipa("BenchRunner", SigningMethod::AdHoc)?;§Output Directory
By default, all mobile artifacts are written to target/mobench/:
target/mobench/
├── android/
│ ├── app/
│ │ ├── src/main/jniLibs/ # Native .so libraries
│ │ └── build/outputs/apk/ # Built APK
│ └── ...
└── ios/
├── sample_fns.xcframework/ # Built xcframework
├── BenchRunner/ # Xcode project
└── BenchRunner.ipa # Packaged IPAThis keeps generated files inside target/, following Rust conventions
and preventing accidental commits of mobile project files.
§Platform Requirements
§Android
- Android NDK (set
ANDROID_NDK_HOMEenvironment variable) cargo-ndk(cargo install cargo-ndk)- Rust targets:
rustup target add aarch64-linux-android - Optional extra ABI targets only when configured explicitly
§iOS
- Xcode with command line tools
uniffi-bindgen(cargo install --git https://github.com/mozilla/uniffi-rs --tag <uniffi-tag> uniffi-bindgen-cli --bin uniffi-bindgen)xcodegen(optional,brew install xcodegen)- Rust targets:
rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
§Best Practices
§Use black_box to Prevent Optimization
Always wrap benchmark results with std::hint::black_box to prevent the
compiler from optimizing away the computation:
#[benchmark]
fn correct_benchmark() {
let result = expensive_computation();
std::hint::black_box(result); // Result is "used"
}§Avoid Side Effects
Benchmarks should be deterministic and avoid I/O operations:
// Good: Pure computation
#[benchmark]
fn good_benchmark() {
let data = vec![1, 2, 3, 4, 5];
let sum: i32 = data.iter().sum();
std::hint::black_box(sum);
}
// Avoid: File I/O adds noise
#[benchmark]
fn noisy_benchmark() {
let data = std::fs::read_to_string("data.txt").unwrap(); // Don't do this
std::hint::black_box(data);
}§Choose Appropriate Iteration Counts
- Warmup: 5-10 iterations to warm CPU caches and JIT
- Iterations: 50-100 for stable statistics
- Mobile devices may have more variance than desktop
§License
MIT License - see repository for details.
Re-exports§
pub use native_c_abi::MobenchBuf;registrypub use registry::BenchFunction;registrypub use registry::discover_benchmarks;registrypub use registry::find_benchmark;registrypub use registry::list_benchmark_names;registrypub use runner::BenchmarkBuilder;registrypub use runner::run_benchmark;registrypub use types::BenchError;pub use types::BenchSample;pub use types::BenchSpec;pub use types::HarnessTimelineSpan;pub use types::RunnerReport;pub use types::BuildConfig;pub use types::BuildProfile;pub use types::BuildResult;pub use types::FfiBackend;pub use types::InitConfig;pub use types::NativeLibraryArtifact;pub use types::Target;pub use timing::BenchSummary;pub use timing::SemanticPhase;pub use timing::TimingError;pub use timing::profile_phase;pub use timing::run_closure;pub use inventory;registry
Modules§
- builders
builders - Build automation for mobile platforms.
- codegen
codegen - Code generation and template management
- ffi
- Unified FFI module for UniFFI integration.
- native_
c_ abi registry - Native JSON C ABI for benchmark runners.
- registry
registry - Benchmark function registry
- runner
registry - Benchmark execution runtime
- timing
- Lightweight benchmarking harness for mobile platforms.
- types
- Core types for mobench-sdk.
- uniffi_
types - UniFFI integration helpers for generating mobile bindings.
Macros§
- debug_
benchmarks registry - Generates a debug function that prints all discovered benchmarks.
- export_
native_ c_ abi registry - Exports the stable mobench native JSON C ABI symbols from a benchmark crate.
Constants§
- VERSION
- Library version, matching
Cargo.toml.
Functions§
- black_
box - Re-export of
std::hint::black_boxfor preventing compiler optimizations.
Attribute Macros§
- benchmark
registry - Marks a function as a benchmark for mobile execution.