pub struct Benchmarks<C, W, E>where
    C: Clone + Display,
    W: Clone + Display,
    Error: From<E>,{ /* private fields */ }
Expand description

Run and analyze a benchmarks suite

  • C - configuration
  • W - workload unit
  • E - error type

Implementations§

source§

impl<C, W, E> Benchmarks<C, W, E>where C: Clone + Display, W: Clone + Display, Error: From<E>,

source

pub fn new(name: &str) -> Benchmarks<C, W, E>

Create a new Benchmarks

  • name - the name of the benchmark session
Examples found in repository?
examples/benchmark_example.rs (line 11)
10
11
12
13
14
15
16
17
18
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    benchmarks.add("A Simple Benchmark", example, "No Configuration", (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    Ok(())
}
More examples
Hide additional examples
examples/benchmark_analysis_example.rs (line 35)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}
source

pub fn run(&mut self) -> Result<(), Error>

Run all benchmarks

Examples found in repository?
examples/benchmark_example.rs (line 13)
10
11
12
13
14
15
16
17
18
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    benchmarks.add("A Simple Benchmark", example, "No Configuration", (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    Ok(())
}
More examples
Hide additional examples
examples/benchmark_analysis_example.rs (line 38)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}
source

pub fn add( &mut self, name: &str, f: fn(stop_watch: &mut StopWatch, config: C, workload_point: W) -> Result<(), E>, config: C, work: Vec<W>, repeat: usize, ramp_up: usize ) -> Result<(), Error>

Create and add a Benchmark

  • name - the name of the benchmark series. The result will be accessible by the name as a key from the summary.
  • f - the function that runs the benchmark.
  • config - the configuration value for this benchmark series
  • work - workload points vector for this benchmark series. Elements of this vector are passed to f in each iteration
  • repeat - number of times the benchmark will be repeated
  • ramp_up - number of times the benchmark will be performed before the measurement is taken
Examples found in repository?
examples/benchmark_example.rs (line 12)
10
11
12
13
14
15
16
17
18
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    benchmarks.add("A Simple Benchmark", example, "No Configuration", (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    Ok(())
}
More examples
Hide additional examples
examples/benchmark_analysis_example.rs (line 37)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}
source

pub fn summary(&self) -> Summary

Produce Summary for all series

source

pub fn summary_as_json(&self) -> String

Produce Summary for all series as JSON string.

Examples found in repository?
examples/benchmark_example.rs (line 15)
10
11
12
13
14
15
16
17
18
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    benchmarks.add("A Simple Benchmark", example, "No Configuration", (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    Ok(())
}
More examples
Hide additional examples
examples/benchmark_analysis_example.rs (line 40)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}
source

pub fn csv_headers(&self) -> String

Produce headers for Self::summary_as_csv method

Examples found in repository?
examples/benchmark_analysis_example.rs (line 42)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}
source

pub fn summary_as_csv(&self) -> HashMap<String, Vec<String>>

Produce summary for each series as vector of CSV lines. The key for series data is the series name used in Self::add method, values are placed as the headers returned by Self::csv_headers

Examples found in repository?
examples/benchmark_analysis_example.rs (line 43)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}
source

pub fn configs(&self) -> HashMap<String, String>

Produce description of configurations for each series. The key for series config is the series name used in Self::add method.

source

pub fn name(&self) -> &String

The benchmarks suite name

source

pub fn analyze( &self, prev_result_string_opt: Option<String>, threshold: f64 ) -> Result<AnalysisResult, Error>

Compare the current result against a previous result.

  • prev_result_string_opt - a JSON string of the Summary of previous run
  • threshold - threshold used to determine equality.
Examples found in repository?
examples/benchmark_analysis_example.rs (line 53)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() -> Result<(), anyhow::Error> {
    let mut benchmarks = Benchmarks::new("Example");
    let workloads: BTreeMap<u64, Duration> = (0..=10).map(|i| (i, Duration::from_millis(i))).collect();
    benchmarks.add("Another Benchmark", example, Config { workloads }, (1..=10).collect(), 2, 1)?;
    benchmarks.run()?;

    let summary = benchmarks.summary_as_json();
    println!("Summary: {summary}");
    let csv_headers = benchmarks.csv_headers();
    let csv_data = benchmarks.summary_as_csv();
    for (k, v) in csv_data {
        println!("Benchmark name: {k}");
        println!("{csv_headers}");
        for line in v {
            println!("{line}")
        }
    }

    // ignore new series
    let analysis_result = benchmarks.analyze(None, 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    // compare results with threshold of 5 percent
    let analysis_result = benchmarks.analyze(Some(summary), 5.0)?;
    println!("Analysis result: {}", analysis_result.to_string());
    Ok(())
}

Auto Trait Implementations§

§

impl<C, W, E> RefUnwindSafe for Benchmarks<C, W, E>where C: RefUnwindSafe, W: RefUnwindSafe,

§

impl<C, W, E> Send for Benchmarks<C, W, E>where C: Send, W: Send,

§

impl<C, W, E> Sync for Benchmarks<C, W, E>where C: Sync, W: Sync,

§

impl<C, W, E> Unpin for Benchmarks<C, W, E>where C: Unpin, W: Unpin,

§

impl<C, W, E> UnwindSafe for Benchmarks<C, W, E>where C: UnwindSafe, W: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
§

impl<SS, SP> SupersetOf<SS> for SPwhere SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V