native/core/benches/perf.rs (34 lines of code) (raw):

// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. use std::{fs::File, os::raw::c_int, path::Path}; use criterion::profiler::Profiler; use pprof::ProfilerGuard; /// A custom profiler for criterion which generates flamegraph. /// /// Mostly followed this blog post: https://www.jibbow.com/posts/criterion-flamegraphs/ /// After `cargo bench --bench <bench-name> -- --profile-time=<time>` /// You can find flamegraph.svg under `target/criterion/<bench-name>/<bench-method-name>/profile` pub struct FlamegraphProfiler<'a> { frequency: c_int, active_profiler: Option<ProfilerGuard<'a>>, } impl FlamegraphProfiler<'_> { pub fn new(frequency: c_int) -> Self { FlamegraphProfiler { frequency, active_profiler: None, } } } impl Profiler for FlamegraphProfiler<'_> { fn start_profiling(&mut self, _benchmark_id: &str, _benchmark_dir: &Path) { self.active_profiler = Some(ProfilerGuard::new(self.frequency).unwrap()); } fn stop_profiling(&mut self, _benchmark_id: &str, benchmark_dir: &Path) { std::fs::create_dir_all(benchmark_dir).unwrap(); let flamegraph_path = benchmark_dir.join("flamegraph.svg"); let flamegraph_file = File::create(flamegraph_path).expect("File system error while creating flamegraph.svg"); if let Some(profiler) = self.active_profiler.take() { profiler .report() .build() .unwrap() .flamegraph(flamegraph_file) .expect("Error writing flamegraph"); } } }