mobench-macros 0.1.45

Procedural macros for mobench benchmarks with setup, teardown, and per-iteration support
Documentation
# mobench-macros

Procedural macros for the [mobench](https://crates.io/crates/mobench) mobile
benchmarking toolkit.

This crate provides the `#[benchmark]` attribute macro. The macro preserves the
annotated Rust function, validates the benchmark signature at compile time, and
registers it through `inventory` so `mobench-sdk` and the `cargo mobench` CLI
can discover and run it.

Current release: **0.1.45**.

## Install

Most users should depend on `mobench-sdk`, which re-exports the macro:

```toml
[dependencies]
mobench-sdk = "0.1.45"
inventory = "0.3"
```

Direct macro use is also supported:

```toml
[dependencies]
mobench-macros = "0.1.45"
mobench-sdk = { version = "0.1.45", default-features = false, features = ["registry"] }
inventory = "0.3"
```

## Basic Example

```rust
use mobench_sdk::benchmark;

#[benchmark]
pub fn fibonacci_benchmark() {
    let result = fibonacci(30);
    std::hint::black_box(result);
}

fn fibonacci(n: u32) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n - 1) + fibonacci(n - 2),
    }
}
```

## Setup, Teardown, and Per-Iteration Input

Setup code runs outside measured timing:

```rust
use mobench_sdk::benchmark;

fn setup_data() -> Vec<u8> {
    vec![42; 1024 * 1024]
}

#[benchmark(setup = setup_data)]
pub fn checksum(data: &Vec<u8>) {
    let sum: u64 = data.iter().map(|b| *b as u64).sum();
    std::hint::black_box(sum);
}
```

Use `per_iteration` when the benchmark mutates or consumes its input:

```rust
use mobench_sdk::benchmark;

fn unsorted_vec() -> Vec<i32> {
    (0..1000).rev().collect()
}

#[benchmark(setup = unsorted_vec, per_iteration)]
pub fn sort_vec(mut data: Vec<i32>) {
    data.sort();
    std::hint::black_box(data);
}
```

Teardown can clean up resources after measured iterations:

```rust
use mobench_sdk::benchmark;

fn setup_db() -> Database {
    Database::connect("bench.db")
}

fn cleanup_db(db: Database) {
    db.close();
}

#[benchmark(setup = setup_db, teardown = cleanup_db)]
pub fn query(db: &Database) {
    db.query("SELECT 1");
}
```

## Signature Rules

- Simple benchmarks take no parameters and return `()`.
- Setup benchmarks take one parameter matching the setup function output.
- `per_iteration` setup passes the setup value by value.
- Non-`per_iteration` setup passes the setup value by reference.
- Benchmark functions should be `pub` when they need to be linked into generated
  mobile runners.

## How It Works

`#[benchmark]` expands to registration code similar to:

```rust
inventory::submit! {
    mobench_sdk::BenchFunction {
        name: "my_crate::my_benchmark",
        runner: |spec| {
            mobench_sdk::timing::run_closure(spec, || {
                my_benchmark();
                Ok(())
            })
        },
    }
}
```

The `cargo mobench list`, `verify`, `run`, and `ci run` commands use that
registry through the SDK runtime.

## License

MIT licensed, World Foundation 2026.