Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions canbench-bin/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ fn reports_scopes_in_new_benchmark() {

Benchmark: bench_scope_new (new)
total:
instructions: 3988 (new)
instructions: 4626 (new)
heap_increase: 1 pages (new)
stable_memory_increase: 0 pages (new)

Expand Down Expand Up @@ -356,7 +356,7 @@ fn reports_scopes_in_existing_benchmark() {

Benchmark: bench_scope_exists
total:
instructions: 3988 (regressed from 0)
instructions: 4626 (regressed from 0)
heap_increase: 1 pages (regressed from 0)
stable_memory_increase: 0 pages (no change)

Expand Down Expand Up @@ -489,3 +489,57 @@ Instruction traces written to write_stable_memory.svg
);
});
}

#[test]
fn reports_repeated_scope_in_new_benchmark() {
BenchTest::canister("measurements_output")
.with_bench("bench_repeated_scope_new")
.run(|output| {
assert_success!(
output,
"
---------------------------------------------------

Benchmark: bench_repeated_scope_new (new)
total:
instructions: 16.97 K (new)
heap_increase: 1 pages (new)
stable_memory_increase: 0 pages (new)

scope_1 (scope):
instructions: 8694 (new)
heap_increase: 1 pages (new)
stable_memory_increase: 0 pages (new)

---------------------------------------------------
"
);
});
}

#[test]
fn reports_repeated_scope_in_existing_benchmark() {
BenchTest::canister("measurements_output")
.with_bench("bench_repeated_scope_exists")
.run(|output| {
assert_success!(
output,
"
---------------------------------------------------

Benchmark: bench_repeated_scope_exists
total:
instructions: 16.97 K (regressed from 0)
heap_increase: 1 pages (regressed from 0)
stable_memory_increase: 0 pages (no change)

scope_1 (scope):
instructions: 8694 (regressed by 986.75%)
heap_increase: 1 pages (improved by 91.67%)
stable_memory_increase: 0 pages (no change)

---------------------------------------------------
"
);
});
}
51 changes: 32 additions & 19 deletions canbench-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,10 @@
pub use canbench_rs_macros::bench;
use candid::CandidType;
use serde::{Deserialize, Serialize};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::{cell::RefCell, collections::BTreeMap, ops::Add};

thread_local! {
static SCOPES: RefCell<BTreeMap<&'static str, Measurement>> =
static SCOPES: RefCell<BTreeMap<&'static str, Vec<Measurement>>> =
const { RefCell::new(BTreeMap::new()) };
}

Expand Down Expand Up @@ -500,6 +499,18 @@ pub struct Measurement {
pub stable_memory_increase: u64,
}

impl Add for Measurement {
type Output = Self;

fn add(self, other: Self) -> Self::Output {
Self {
instructions: self.instructions + other.instructions,
heap_increase: self.heap_increase + other.heap_increase,
stable_memory_increase: self.stable_memory_increase + other.stable_memory_increase,
}
}
}

/// Benchmarks the given function.
pub fn bench_fn<R>(f: impl FnOnce() -> R) -> BenchResult {
reset();
Expand Down Expand Up @@ -614,20 +625,11 @@ impl Drop for BenchScope {

SCOPES.with(|p| {
let mut p = p.borrow_mut();
let prev_scope = p.insert(
self.name,
Measurement {
instructions,
heap_increase,
stable_memory_increase,
},
);

assert!(
prev_scope.is_none(),
"scope {} cannot be specified multiple times.",
self.name
);
p.entry(self.name).or_default().push(Measurement {
instructions,
heap_increase,
stable_memory_increase,
});
});
}
}
Expand All @@ -637,9 +639,20 @@ fn reset() {
SCOPES.with(|p| p.borrow_mut().clear());
}

// Returns the measurements for any declared scopes.
// Returns the measurements for any declared scopes,
// aggregated by the scope name.
fn get_scopes_measurements() -> std::collections::BTreeMap<&'static str, Measurement> {
SCOPES.with(|p| p.borrow().clone())
SCOPES
.with(|p| p.borrow().clone())
.into_iter()
.map(|(scope, measurements)| {
let mut total = Measurement::default();
for measurement in measurements {
total = total + measurement;
}
(scope, total)
})
.collect()
}

fn instruction_count() -> u64 {
Expand Down
11 changes: 11 additions & 0 deletions tests/measurements_output/canbench_results.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ benches:
instructions: 0
stable_memory_increase: 0

scopes:
scope_1:
heap_increase: 12
instructions: 800
# A benchmark that is expected to return an increase of new repeated scope steps.
bench_repeated_scope_exists:
total:
heap_increase: 0
instructions: 0
stable_memory_increase: 0

scopes:
scope_1:
heap_increase: 12
Expand Down
22 changes: 22 additions & 0 deletions tests/measurements_output/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,28 @@ fn bench_scope_exists() {
}
}

// A benchmark that includes a repeated scope, but isn't persisted in the results.
#[bench]
fn bench_repeated_scope_new() {
{
for _ in 0..10 {
let _p = bench_scope("scope_1");
println!("do something");
}
}
}

// A benchmark that includes a repeated scope and is persisted in the results.
#[bench]
fn bench_repeated_scope_exists() {
{
for _ in 0..10 {
let _p = bench_scope("scope_1");
println!("do something");
}
}
}

#[export_name = "canister_query __canbench__broken_benchmark"]
fn broken_benchmark() {
// This benchmark doesn't reply, and will therefore fail.
Expand Down