gbench 1.0.1

This crate provides the tools to benchmark code for further analyzation using Chrome tracing
Documentation

This crate provides the tools to benchmark code for further analyzation using different tools.

Writers System

This crate uses writers system to manage collected data. This means that all the macros that collect data during program running push this data in form of BenchData enums to a shared storage. At the end of the program all the data is given to the instances of Writer that are given at the initialization.

Examples

Examples of using gbench basic functionality

use gbench::{instantiate, scope, ChromeTracing};
fn main() {
// Istantiation of the global variables
// It is needed at the top of every program that uses gbench
// The folder that is specified is the folder where the data
// will be saved
instantiate!(ChromeTracing("target/bench"));
{
// This macro creates a variable that starts benchmarking
// on creation and saves the result on drop.
// The variable name is the first argument, the scope name
// is the second.
scope!(sc | "Scope");
for _ in 0..1_000_000 {
let _a = 1 + 1;
}
}
}

Example of a log! macro use

use gbench::{instantiate, log, scope, ChromeTracing};

fn main() {
instantiate!(ChromeTracing("target/bench"));
{
scope!(sc | "Scope");
for _ in 0..1_000 {
let a = 1 + 1;
// You can log to the file with a timestamp
// using log! macro
log!("A = {}", a);
}
}
}

Example of a count! macro and CsvWriter writer use

use gbench::{count, instantiate, scope, ChromeTracing, CsvWriter};

fn main() {
// Additionally CsvWriter will save all the counter data in
// a csv table
instantiate!(ChromeTracing("target/bench"), CsvWriter("target/bench"));
{
scope!(sc | "Scope");
for i in 0..1000 {
let val = i * i;
// This statement writes val to field "val" of counter "Actual value"
// and writes i to field "i" of counter "I"
count! {
"Actual value" => {
"val" => val
},
"I" => {
"i" => i
}
}
}
}
}

Full example

use gbench::{instantiate, scope, ChromeTracing};
use std::thread;
fn calculate(num: f32, n: u32) -> f32 {
(0..n)
.fold((num, 0.0), |(x, v), _| (x + v * 0.01, v - x * 0.001))
.0
}

fn main() {
instantiate!(ChromeTracing("target/bench"));

scope!(program_scope | "Program scope");
// Doing the work that needs benchmarking
for _ in 0..5 {
scope!(main | "Main scope");
// Spawning a thread to do work
let thread = thread::spawn(move || {
// This benchmarks the scope that it is in
scope!(child | "Child");
calculate(1.0, 1_500_000)
});
// You can organize your subtasks in scopes to
// benchmark them
scope!(imp | "An important task");
{
scope!(i1 | "Important subtask");
calculate(1.0, 300_000);
}
{
scope!(i2 | "Less important subtask");
calculate(1.0, 500_000);
}
// If the block of code that you need to benchmark
// has ended you can drop the guard if the scope
// has not ended
drop(imp);
// Marking the start of another task
scope!(join | "Joining thread");
thread.join().unwrap();
// This line of code is unnecessary but I like
// to keep it
drop(join);
}
}