iai_callgrind

Macro 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; $(;)* )?
        $( setup = $setup:expr ; $(;)* )?
        $( teardown = $teardown:expr ; $(;)* )?
        binary_benchmark_groups =
    ) => { ... };
    (
        $( config = $config:expr; $(;)* )?
        $( setup = $setup:expr ; $(;)* )?
        $( teardown = $teardown:expr ; $(;)* )?
        binary_benchmark_groups = $( $group:ident ),+ $(,)*
    ) => { ... };
    (
        $( config = $config:expr; $(;)* )?
        $( setup = $setup:expr ; $(;)* )?
        $( teardown = $teardown:expr ; $(;)* )?
        library_benchmark_groups =
    ) => { ... };
    (
        $( config = $config:expr ; $(;)* )?
        $( setup = $setup:expr ; $(;)* )?
        $( teardown = $teardown:expr ; $(;)* )?
        library_benchmark_groups = $( $group:ident ),+ $(,)*
    ) => { ... };
    (
        callgrind_args = $( $args:literal ),* $(,)*; $(;)*
        functions = $( $func_name:ident ),+ $(,)*
    ) => { ... };
    ( $( $func_name:ident ),+ $(,)* ) => { ... };
}
Available on crate feature default only.
Expand description

The iai_callgrind::main macro expands to a main function which runs all 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 in this order (separated by a semicolon):

  • config (optional): Optionally specify a crate::LibraryBenchmarkConfig valid for all benchmark groups
  • setup (optional): A setup function or any valid expression which is run before all benchmarks
  • teardown (optional): A setup function or any valid expression which is run after all benchmarks
  • library_benchmark_groups (mandatory): The name of one or more library_benchmark_group! macros. Multiple names are expected to be a comma separated list

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

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

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 callgrind arguments via crate::LibraryBenchmarkConfig::callgrind_args:

main!(
    config = LibraryBenchmarkConfig::default()
                .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

Setting up binary benchmarks is almost the same as setting up library benchmarks but using the #[binary_benchmark] macro. For example, if you’re crate’s binary is called my-foo:

use iai_callgrind::{main, binary_benchmark_group, binary_benchmark};

#[binary_benchmark]
#[bench::hello_world("hello world")]
#[bench::foo("foo")]
fn bench_binary(arg: &str) -> iai_callgrind::Command {
    iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-foo"))
        .arg(arg)
        .build()
}

binary_benchmark_group!(
    name = my_group;
    benchmarks = bench_binary
);

main!(binary_benchmark_groups = my_group);

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