fn my_function() {
puffin::profile_function!();
...
if ... {
puffin::profile_scope!("load_image", image_name);
...
}
}
The Puffin macros write data to a thread-local data stream. When the outermost scope of a thread is closed, the data stream is sent to a global profiler collector. The scopes are pretty light-weight, costing around 60 ns on an M1 MacBook Pro.
You have to turn on the profiler before it captures any data with a call to puffin::set_scopes_on(true);
. When the profiler is off the profiler scope macros only has an overhead of 1 ns on an M1 MacBook Pro (plus some stack space).
Once per frame you need to call puffin::GlobalProfiler::lock().new_frame();
.
You can use puffin_http
to send profile events over TCP to puffin_viewer
. This is as easy as:
fn main() {
let server_addr = format!("127.0.0.1:{}", puffin_http::DEFAULT_PORT);
let _puffin_server = puffin_http::Server::new(&server_addr).unwrap();
eprintln!("Run this to view profiling data: puffin_viewer {server_addr}");
puffin::set_scopes_on(true);
…
// You also need to periodically call
// `puffin::GlobalProfiler::lock().new_frame();`
// to flush the profiling events.
}
egui integration
To view the profile data in-game you can use puffin_egui
.
If you are using eframe
you can look at this example.
Also check out the crate profiling
which provides a unifying layer of abstraction on top of puffin
and other profiling crates.
We welcome community contributions to this project.
Please read our Contributor Guide for more information on how to get started.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.