Skip to main content

ic_testkit/
performance.rs

1//! Canister-side benchmark marker emission using IC execution counters.
2
3use crate::benchmark::{BenchmarkCounters, DEFAULT_PREFIX, format_marker};
4
5const WASM_PAGE_BYTES: u128 = 65_536;
6
7/// Capture and emit compact benchmark counter markers.
8pub struct Performance;
9
10impl Performance {
11    /// Print one `ICTK` marker for `label` using the current counters.
12    ///
13    /// Pair labels ending in `:start` and `:end` for host-side span analysis.
14    pub fn measure(label: &str) {
15        ic_cdk::api::debug_print(format_marker(DEFAULT_PREFIX, label, Self::counters()));
16    }
17
18    /// Read the instruction, Wasm heap, stable-memory, and allocation counters.
19    ///
20    /// `total_allocation` is currently reserved and emitted as zero.
21    #[must_use]
22    pub fn counters() -> BenchmarkCounters {
23        BenchmarkCounters {
24            instructions: u128::from(ic_cdk::api::call_context_instruction_counter()),
25            heap_bytes: wasm_memory_size_bytes(),
26            memory_bytes: u128::from(ic_cdk::api::stable_size()) * WASM_PAGE_BYTES,
27            total_allocation: 0,
28        }
29    }
30}
31
32#[cfg(target_arch = "wasm32")]
33fn wasm_memory_size_bytes() -> u128 {
34    u128::try_from(core::arch::wasm32::memory_size(0)).expect("usize fits into u128")
35        * WASM_PAGE_BYTES
36}
37
38#[cfg(not(target_arch = "wasm32"))]
39const fn wasm_memory_size_bytes() -> u128 {
40    0
41}