Install the published crate:
cargo add timescopeOr add it to Cargo.toml:
[dependencies]
timescope = "0.1.0"Put timescope::scope! at the beginning of a function or block.
use std::thread;
fn load_assets() {
timescope::scope!(load_assets);
// work to profile
{
// This is recorded as a child of `load_assets`.
timescope::scope!("load asset inner");
// work to profile
let handle = thread::spawn(|| {
// Register a readable thread name.
timescope::register_thread_name("sub thread");
// A different thread is detected and recorded as a new root.
timescope::scope!("load asset sub thread");
// work to profile
});
handle.join().unwrap();
}
}
fn main() -> std::io::Result<()> {
// Register a readable thread name.
timescope::register_thread_name("main thread");
load_assets();
// Write analysis results to files.
// Dumping also works correctly from another thread.
timescope::dump_to_dir("target/timescope")?;
Ok(())
}This writes:
target/timescope/summary.txt
target/timescope/report.html
summary.txt is designed in an AI-friendly format.
Use this when you want to log or inspect the report directly.
timescope::scope!(tick);
let summary = timescope::dump_to_summary_string();
println!("{summary}");Use this when you want to serve or embed the report yourself.
fn main() -> std::io::Result<()> {
timescope::scope!(render_frame);
let html = timescope::dump_to_html_string();
std::fs::write("target/timescope/report.html", html)?;
Ok(())
}fn main() -> std::io::Result<()> {
let options = timescope::DumpOptions {
summary_title: "Server Profile Summary".to_owned(),
html_title: "Server Profile Report".to_owned(),
};
timescope::dump_to_dir_with_options("target/timescope", &options)?;
Ok(())
}Register a readable name once per thread.
timescope::register_thread_name("worker thread");
timescope::scope!(worker_loop);The registered name appears in both summary.txt and report.html.
Set runtime options before profiling starts.
timescope::set_time_scope_settings(timescope::TimeScopeSettings {
history_size: 120,
});Existing scopes keep their current history buffer capacity.
Use this when profiling should stay compiled in, but should be paused at runtime.
timescope::enable_profile(false);
timescope::scope!(ignored_work);
timescope::enable_profile(true);
timescope::scope!(measured_work);The profile feature is enabled by default. Disable it to make scope! a
compile-time no-op.
[dependencies]
timescope = { version = "0.1.0", default-features = false }You can also use command-line cfg flags. Command-line cfg has priority over the Cargo feature.
RUSTFLAGS="--cfg timescope_profile_disabled" cargo run
RUSTFLAGS="--cfg timescope_profile_enabled" cargo run --no-default-featuresIf both flags are set, timescope_profile_disabled wins.
Reports include:
% Total% Parent- average milliseconds
+-milliseconds- min / max milliseconds
- total milliseconds
- call count
- loop call ratio
- recent millisecond history, 60 samples by default
The HTML report also includes a collapsible tree, a total-percent bar, and
history sparklines. total, % Total, % Parent, and average milliseconds use
all recorded calls. history_ms and sparklines show the recent history window.
