diff --git a/matrix_sdk_crypto/Cargo.toml b/matrix_sdk_crypto/Cargo.toml index a14cf0f6..99d35532 100644 --- a/matrix_sdk_crypto/Cargo.toml +++ b/matrix_sdk_crypto/Cargo.toml @@ -52,6 +52,7 @@ http = "0.2.3" matrix-sdk-test = { version = "0.2.0", path = "../matrix_sdk_test" } indoc = "1.0.3" criterion = { version = "0.3.4", features = ["async", "async_futures", "html_reports"] } +pprof = { version = "0.4.2", features = ["flamegraph"] } [[bench]] name = "crypto_bench" diff --git a/matrix_sdk_crypto/benches/crypto_bench.rs b/matrix_sdk_crypto/benches/crypto_bench.rs index 1a9e1501..e715dd92 100644 --- a/matrix_sdk_crypto/benches/crypto_bench.rs +++ b/matrix_sdk_crypto/benches/crypto_bench.rs @@ -1,9 +1,8 @@ +mod perf; + use std::convert::TryFrom; -use criterion::{ - async_executor::FuturesExecutor, criterion_group, criterion_main, BatchSize, BenchmarkId, - Criterion, Throughput, -}; +use criterion::{async_executor::FuturesExecutor, *}; use futures::executor::block_on; use matrix_sdk_common::{ @@ -101,5 +100,13 @@ pub fn keys_claiming(c: &mut Criterion) { group.finish() } -criterion_group!(benches, keys_query, keys_claiming); +fn criterion() -> Criterion { + Criterion::default().with_profiler(perf::FlamegraphProfiler::new(100)) +} + +criterion_group! { + name = benches; + config = criterion(); + targets = keys_query, keys_claiming +} criterion_main!(benches); diff --git a/matrix_sdk_crypto/benches/perf.rs b/matrix_sdk_crypto/benches/perf.rs new file mode 100644 index 00000000..a23bf872 --- /dev/null +++ b/matrix_sdk_crypto/benches/perf.rs @@ -0,0 +1,78 @@ +//! This is a simple Criterion Profiler implementation using pprof. +//! +//! It's mostly a direct copy from here: https://www.jibbow.com/posts/criterion-flamegraphs/ +use std::{fs::File, os::raw::c_int, path::Path}; + +use criterion::profiler::Profiler; +use pprof::ProfilerGuard; + +/// Small custom profiler that can be used with Criterion to create a flamegraph for benchmarks. +/// Also see [the Criterion documentation on this][custom-profiler]. +/// +/// ## Example on how to enable the custom profiler: +/// +/// ``` +/// mod perf; +/// use perf::FlamegraphProfiler; +/// +/// fn fibonacci_profiled(criterion: &mut Criterion) { +/// // Use the criterion struct as normal here. +/// } +/// +/// fn custom() -> Criterion { +/// Criterion::default().with_profiler(FlamegraphProfiler::new()) +/// } +/// +/// criterion_group! { +/// name = benches; +/// config = custom(); +/// targets = fibonacci_profiled +/// } +/// ``` +/// +/// The neat thing about this is that it will sample _only_ the benchmark, and not other stuff like +/// the setup process. +/// +/// Further, it will only kick in if `--profile-time