Macro iai_callgrind::main

source ·
macro_rules! main {
    ( $( options = $( $options:literal ),+ $(,)*; )?
      $( before = $before:ident $(, bench = $bench_before:literal )? ; )?
      $( after = $after:ident $(, bench = $bench_after:literal )? ; )?
      $( setup = $setup:ident $(, bench = $bench_setup:literal )? ; )?
      $( teardown = $teardown:ident $(, bench = $bench_teardown:literal )? ; )?
      $( sandbox = $sandbox:literal; )?
      $( fixtures = $fixtures:literal $(, follow_symlinks = $follow_symlinks:literal )? ; )?
      $( run = cmd = $cmd:expr
            $(, envs = [ $( $envs:literal ),* $(,)* ] )?,
            $( id = $id:literal, args = [ $( $args:literal ),* $(,)* ]  ),+ $(,)*
      );+ $(;)*
    ) => { ... };
    (
        $( config = $config:expr; $(;)* )?
        binary_benchmark_groups =
    ) => { ... };
    (
        $( config = $config:expr; $(;)* )?
        binary_benchmark_groups = $( $group:ident ),+ $(,)*
    ) => { ... };
    (
        $( config = $config:expr; $(;)* )?
        library_benchmark_groups =
    ) => { ... };
    (
        $( config = $config:expr ; $(;)* )?
        library_benchmark_groups = $( $group:ident ),+ $(,)*
    ) => { ... };
    (
        callgrind_args = $( $args:literal ),* $(,)*; $(;)*
        functions = $( $func_name:ident ),+ $(,)*
    ) => { ... };
    ( $( $func_name:ident ),+ $(,)* ) => { ... };
}
Expand description

The iai_callgrind::main macro expands to a main function which runs all of the benchmarks.

Using Iai-callgrind requires disabling the benchmark harness. This can be done like so in the Cargo.toml file:

[[bench]]
name = "my_bench"
harness = false

To be able to run any iai-callgrind benchmarks, you’ll also need the iai-callgrind-runner installed with the binary somewhere in your $PATH for example with

cargo install iai-callgrind-runner

my_bench has to be a rust file inside the ‘benches’ directory.

Library Benchmarks

The crate::main macro has one form to run library benchmarks:

main!(library_benchmark_groups = some_group);

which accepts the following top-level arguments:

A library benchmark consists of library_benchmark_groups and with #[library_benchmark] annotated benchmark functions.

use iai_callgrind::{black_box, main, library_benchmark_group, library_benchmark};

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

#[library_benchmark]
#[bench::short(10)]
#[bench::long(30)]
fn bench_fibonacci(value: u64) -> u64 {
    black_box(fibonacci(value))
}

library_benchmark_group!(
    name = bench_fibonacci_group;
    benchmarks = bench_fibonacci
);

main!(library_benchmark_groups = bench_fibonacci_group);

If you need to pass arguments to valgrind’s callgrind, you can specify raw callgrind arguments via the crate::LibraryBenchmarkConfig:

main!(
    config = LibraryBenchmarkConfig::default()
                .raw_callgrind_args(
                    ["--arg-with-flags=yes", "arg-without-flags=is_ok_too"]
                );
    library_benchmark_groups = some_group
);

See also Callgrind Command-line options.

For an in-depth description of library benchmarks and more examples see the README#Library Benchmarks of this crate.

Binary Benchmarks

The scheme to setup binary benchmarks makes use of crate::binary_benchmark_group and crate::BinaryBenchmarkGroup to set up benches with crate::Run roughly looking like this:

use iai_callgrind::{main, binary_benchmark_group, Run, Arg};

binary_benchmark_group!(
    name = my_group;
    benchmark = |"my-exe", group: &mut BinaryBenchmarkGroup| {
        group
        .bench(Run::with_arg(Arg::new(
            "positional arguments",
            ["foo", "foo bar"],
        )))
        .bench(Run::with_arg(Arg::empty("no argument")));
    }
);

main!(binary_benchmark_groups = my_group);

See the documentation of crate::binary_benchmark_group and crate::Run for more details.