pub struct Command(/* private fields */);
default
only.Expand description
Provide the Command
to be benchmarked
Command
is a builder for the binary which is going to be benchmarked providing fine-grained
control over how the Command
for the valgrind benchmark should be executed.
The default configuration is created with Command::new
providing a path to an executable.
Adding a crate’s binary is usually done with env!("CARGO_BIN_EXE_<name>")
where <name>
is
the name of the binary. The builder methods allow the configuration to be changed prior to
Command::build
. The Command
can be reused to build multiple processes.
§Examples
Suppose your crate’s binary is called my-echo
:
use iai_callgrind::Command;
let command = Command::new(env!("CARGO_BIN_EXE_my-echo"));
However, an iai-callgrind benchmark is not limited to a crate’s binaries, it can be any
executable in the $PATH
, or an absolute path to a binary installed on your system. The
following will create a Command
for the system’s echo
from the $PATH
:
use iai_callgrind::Command;
let command = Command::new("echo");
Implementations§
source§impl Command
impl Command
sourcepub fn new<T>(path: T) -> Self
pub fn new<T>(path: T) -> Self
Create a new Command
which is run under valgrind.
Use
env!("CARGO_BIN_EXE_<name>)
to provide the path to an executable of your project instead of target/release/<name>
.
This Command
is a builder for the binary which is going to be benchmarked but is not
executed right away. We simply gather all the information to be finally able to execute the
command under valgrind, later (after we collected all the commands in this benchmark file).
As opposed to std::process::Command
, the build is finalized with Command::build
.
§Relative paths
Relative paths are interpreted relative to the current directory and if not running the
benchmarks in a Sandbox
, depends on where cargo bench
sets the current directory.
Usually, it’s best to use Path::canonicalize
to resolve the relative path to a binary in
your project’s directory. In case you’re running the benchmark in a Sandbox
, the path is
interpreted relative to the root directory of the Sandbox
. Iai-Callgrind tries to resolve
simple names like Command::new("echo")
searching the $PATH
. To disambiguate between
simple names and relative paths, use ./
. For example echo
is searched in the $PATH
and
./echo
is interpreted relative.
§Examples
Assume the project’s binary or one of your project’s binaries name is my-echo
:
use iai_callgrind::Command;
let command = Command::new(env!("CARGO_BIN_EXE_my-echo"));
or use your system’s echo from the $PATH
with
use iai_callgrind::Command;
let command = Command::new("echo").arg("foo").build();
sourcepub fn delay<T: Into<Delay>>(&mut self, delay: T) -> &mut Self
pub fn delay<T: Into<Delay>>(&mut self, delay: T) -> &mut Self
Delay the execution of the Command
This option allows to delay the Command
execution till a certain event has happened.
Supported events are:
- Timer expired
- File path exists
- TCP/UDP connect succeeded
Delay
can be used in combination with Command::setup_parallel
to wait for an event
that is triggered within the setup()
function. E.g. the setup starts a server that is
needed by the Command
.
§Examples
use iai_callgrind::{binary_benchmark_group, binary_benchmark, main, Command, Delay, DelayKind};
fn start_server() {
// action to start the server, creates pid file
std::fs::File::create("/tmp/my-server.pid").unwrap();
}
#[binary_benchmark]
#[bench::server(setup = start_server)]
fn bench_binary() -> Command {
Command::new(env!("CARGO_BIN_EXE_my-echo"))
.setup_parallel(true)
.delay(Delay::new(DelayKind::PathExists("/tmp/my-server.pid".into())))
.build()
}
binary_benchmark_group!(name = my_group; benchmarks = bench_binary);
main!(binary_benchmark_groups = my_group);
sourcepub fn setup_parallel(&mut self, setup_parallel: bool) -> &mut Self
pub fn setup_parallel(&mut self, setup_parallel: bool) -> &mut Self
Execute the setup()
in parallel to the Command
.
This option changes the execution flow in a way that the Command
is executed parallel
to the setup
instead of waiting for the setup
to complete.
This can be combined with the usage of Delay
to further control the timing when the
Command
is executed.
§Examples
use std::time::Duration;
use std::net::{SocketAddr, TcpListener};
use std::thread;
use iai_callgrind::{binary_benchmark_group, binary_benchmark, main, Command, Delay, DelayKind};
fn setup_tcp_server() {
thread::sleep(Duration::from_millis(300));
let _listener = TcpListener::bind("127.0.0.1:31000".parse::<SocketAddr>().unwrap()).unwrap();
thread::sleep(Duration::from_secs(1));
}
#[binary_benchmark]
#[bench::delay(setup = setup_tcp_server())]
fn bench_binary() -> iai_callgrind::Command {
Command::new(env!("CARGO_BIN_EXE_my-echo"))
.setup_parallel(true)
.delay(
Delay::new(
DelayKind::TcpConnect("127.0.0.1:31000".parse::<SocketAddr>().unwrap()))
.timeout(Duration::from_millis(500))
).build()
}
binary_benchmark_group!(name = delay; benchmarks = bench_binary);
main!(binary_benchmark_groups = delay);
sourcepub fn arg<T>(&mut self, arg: T) -> &mut Self
pub fn arg<T>(&mut self, arg: T) -> &mut Self
Adds an argument to pass to the Command
This option works exactly the same way as std::process::Command::arg
. To pass multiple
arguments see Command::args
.
§Examples
use iai_callgrind::{binary_benchmark_group, binary_benchmark};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-echo"))
.arg("foo")
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn args<I, T>(&mut self, args: T) -> &mut Self
pub fn args<I, T>(&mut self, args: T) -> &mut Self
Adds multiple arguments to pass to the Command
This option works exactly the same way as std::process::Command::args
.
§Examples
The following will execute my-echo foo
.
use iai_callgrind::{binary_benchmark_group, binary_benchmark};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-echo"))
.arg("foo")
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn stdin<T>(&mut self, stdin: T) -> &mut Self
pub fn stdin<T>(&mut self, stdin: T) -> &mut Self
Configuration for the process’s standard input (Stdin
)
This method takes an Stdin
, Stdio
and everything that implements Into<Stdin>
. The
Stdin
enum mirrors most of the possibilities of std::process::Stdio
but also some
additional possibilities most notably Stdin::Setup
(see there for more details).
Per default, the stdin is not inherited from the parent and any attempt by the child process to read from the stdin stream will result in the stream immediately closing.
The options you might be interested in the most are Stdin::File
, which mirrors the
behaviour of std::process::Stdio
if Stdio
is a std::fs::File
, and
Stdin::Setup
, which is special to iai-callgrind
and lets you pipe the output of
the setup
function into the Stdin of this Command
. If you need to delay the Command
when using Stdin::Setup
, you can do so with Command::delay
.
§Implementation details
As the Command
itself is not executed immediately, the std::process::Stdio
is not
created either. We only use the information from here to create the std::process::Stdio
later after we collected all commands. Setting the Stdin to Inherit
is discouraged and
won’t have the effect you might expect, since the benchmark runner (the parent) uses the
Stdin for its own purposes and closes it before this Command
is executed.
§Examples
Pipe the content of a file (benches/fixture.txt
) into the stdin of this Command
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Stdio};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.stdin(Stdio::File("benches/fixture.txt".into()))
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
Pipe the Stdout of setup into the Stdin of this Command
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Stdin, Pipe};
fn setup_pipe() {
// All output to Stdout of this function will be piped into the Stdin of `my-exe`
println!("This string will be piped into the stdin of my-exe");
}
#[binary_benchmark(setup = setup_pipe())]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.stdin(Stdin::Setup(Pipe::Stdout))
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn stdout<T>(&mut self, stdio: T) -> &mut Self
pub fn stdout<T>(&mut self, stdio: T) -> &mut Self
Configuration for the Command
s standard output (Stdout) handle.
The output of benchmark commands and functions are usually captured by the benchmark runner.
This can be changed for example with the --nocapture
option or here. Any option specified
here takes precedence over the changes which --nocapture
makes to the Stdout of the
command.
§Examples
To see the output of this Command
regardless of --nocapture
in the benchmark output
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Stdio};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.stdout(Stdio::Inherit)
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
To pipe the Stdout into a file /tmp/benchmark.output
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Stdio};
use std::path::PathBuf;
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.stdout(Stdio::File("/tmp/benchmark.output".into()))
// or
.stdout(PathBuf::from("/tmp/benchmark.output"))
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn stderr<T>(&mut self, stdio: T) -> &mut Self
pub fn stderr<T>(&mut self, stdio: T) -> &mut Self
Configuration for the Command
s standard error output (Stderr) handle.
This option is similar to Command::stdout
but configures the Stderr. See there for more
details.
§Examples
To see the error output of this Command
regardless of --nocapture
in the benchmark
output
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Stdio};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.stderr(Stdio::Inherit)
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
To pipe the Stderr into a file /tmp/benchmark.output
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Stdio};
use std::path::PathBuf;
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.stderr(Stdio::File("/tmp/benchmark.output".into()))
// or
.stderr(PathBuf::from("/tmp/benchmark.output"))
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
Add an environment variable available for this Command
These environment variables are available independently of the setting of
BinaryBenchmarkConfig::env_clear
and additive to environment variables added with
BinaryBenchmarkConfig::env
.
§Examples
An example for a custom environment variable “FOO=BAR”:
use iai_callgrind::{binary_benchmark_group, binary_benchmark};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.env("FOO", "BAR")
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn envs<I, K, V>(&mut self, vars: I) -> &mut Self
pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Self
Add multiple environment variables available for this Command
See Command::env
for more details.
§Examples
Add the custom environment variables “FOO=BAR” and BAR=BAZ
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.envs([("FOO", "BAR"), ("BAR", "BAZ")])
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn current_dir<T>(&mut self, value: T) -> &mut Self
pub fn current_dir<T>(&mut self, value: T) -> &mut Self
Set the directory of the benchmarked binary (Default: Unchanged)
See also BinaryBenchmarkConfig::current_dir
§Examples
To set the working directory of your Command
to /tmp
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.current_dir("/tmp")
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
and the following will change the current directory to fixtures
located in the root of the
BinaryBenchmarkConfig::sandbox
use iai_callgrind::{binary_benchmark_group, binary_benchmark, Sandbox, BinaryBenchmarkConfig};
fn setup_sandbox() {
std::fs::create_dir("fixtures").unwrap();
}
#[binary_benchmark(
setup = setup_sandbox(),
config = BinaryBenchmarkConfig::default().sandbox(Sandbox::new(true))
)]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.current_dir("fixtures")
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
sourcepub fn exit_with(&mut self, exit_with: ExitWith) -> &mut Self
pub fn exit_with(&mut self, exit_with: ExitWith) -> &mut Self
Set the expected exit status ExitWith
of this Command
See also BinaryBenchmarkConfig::exit_with
. This setting overwrites the setting of the
BinaryBenchmarkConfig
.
§Examples
If the command is expected to exit with a specific code, for example 100
:
use iai_callgrind::{binary_benchmark_group, binary_benchmark, ExitWith};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.exit_with(ExitWith::Code(100))
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
If a command is expected to fail, but the exit code doesn’t matter:
use iai_callgrind::{binary_benchmark_group, binary_benchmark, ExitWith};
#[binary_benchmark]
fn bench_binary() -> iai_callgrind::Command {
iai_callgrind::Command::new(env!("CARGO_BIN_EXE_my-exe"))
.exit_with(ExitWith::Failure)
.build()
}
binary_benchmark_group!(
name = my_group;
benchmarks = bench_binary
);
Trait Implementations§
source§impl AsRef<Command> for Command
impl AsRef<Command> for Command
source§fn as_ref(&self) -> &InternalCommand
fn as_ref(&self) -> &InternalCommand
source§impl From<&Command> for InternalCommand
impl From<&Command> for InternalCommand
source§impl From<&mut Command> for InternalCommand
impl From<&mut Command> for InternalCommand
source§impl From<Command> for InternalCommand
impl From<Command> for InternalCommand
impl StructuralPartialEq for Command
Auto Trait Implementations§
impl Freeze for Command
impl RefUnwindSafe for Command
impl Send for Command
impl Sync for Command
impl Unpin for Command
impl UnwindSafe for Command
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)