### Setup samply for profiling Source: https://hotpath.rs/cpu_profiling Run the samply setup command to prepare it for attaching to running processes. This may involve signing the binary. ```bash samply setup ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://hotpath.rs/sampling_comparison Clone the hotpath-rs project repository and install the samply profiler to follow along with the examples. ```bash git clone git@github.com:pawurb/hotpath-rs.git cargo install samply ``` -------------------------------- ### Running the Async I/O Example with Hotpath Source: https://hotpath.rs/sampling_comparison Execute the asynchronous file I/O example using Cargo, enabling the 'hotpath' feature and specifying the 'profiling' profile. ```bash cargo run --example profile_async_io --features hotpath --profile profiling ``` -------------------------------- ### Create Benchmark Examples Source: https://hotpath.rs/github_ci Add benchmark examples to your crate using the `#[hotpath::main]` macro to instrument functions for performance tracking. ```rust #[hotpath::main] fn main() { for _ in 0..1000 { my_function(); } } ``` -------------------------------- ### Install hotpath-utils CLI Source: https://hotpath.rs/benchmarks Installs the hotpath-utils CLI tool. Ensure you are using a compatible version. ```bash cargo install hotpath --bin hotpath-utils --version '^0.16.1' --features utils ``` -------------------------------- ### Install hotpath-samply wrapper Source: https://hotpath.rs/cpu_profiling Install the hotpath-samply binary, which acts as a wrapper for samply. Specify the version constraint for compatibility. ```bash cargo install hotpath --bin hotpath-samply --version '^0.16.1' ``` -------------------------------- ### Running CPU-Bound Example with hotpath Source: https://hotpath.rs/sampling_comparison Execute the CPU-bound example using cargo, ensuring the 'hotpath' feature is enabled and the 'profiling' profile is used. This command generates the hotpath profiling report. ```bash cargo run --example profile_cpu --features hotpath --profile profiling ``` -------------------------------- ### Install samply Source: https://hotpath.rs/cpu_profiling Install the samply profiler using cargo. Ensure you use the --locked flag for reproducible builds. ```bash cargo install samply --locked ``` -------------------------------- ### Hotpath Profile Workflow Setup Source: https://hotpath.rs/github_ci Configure the `hotpath-profile` workflow to trigger on pull requests. It checks out code, sets up the Rust toolchain and cache, runs benchmarks on both head and base commits, and uploads metrics as an artifact. Ensure `fetch-depth: 0` is used for `actions/checkout` to get full Git history. ```yaml name: hotpath-profile on: pull_request: permissions: contents: read jobs: profile: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Create metrics directory run: mkdir -p /tmp/metrics - name: Head benchmark (timing) env: HOTPATH_OUTPUT_FORMAT: json HOTPATH_OUTPUT_PATH: /tmp/metrics/head_timing.json run: cargo run --release --example my_benchmark --features='hotpath' - name: Checkout base run: git checkout ${{ github.event.pull_request.base.sha }} - name: Base benchmark (timing) env: HOTPATH_OUTPUT_FORMAT: json HOTPATH_OUTPUT_PATH: /tmp/metrics/base_timing.json run: cargo run --release --example my_benchmark --features='hotpath' - name: Save PR metadata run: | echo '${{ github.event.pull_request.number }}' \ > /tmp/metrics/pr_number.txt echo '${{ github.base_ref }}' > /tmp/metrics/base_ref.txt echo '${{ github.head_ref }}' > /tmp/metrics/head_ref.txt - uses: actions/upload-artifact@v4 with: name: profile-metrics path: /tmp/metrics/ retention-days: 1 ``` -------------------------------- ### Hotpath Comment Workflow Setup Source: https://hotpath.rs/github_ci Configure the `hotpath-comment` workflow to trigger on `workflow_run` of `hotpath-profile`. It downloads artifacts, installs `hotpath-utils`, and posts a profiling diff comment on the PR. This workflow requires `pull-requests: write` permissions. ```yaml name: hotpath-comment on: workflow_run: workflows: ["hotpath-profile"] types: - completed permissions: contents: read pull-requests: write jobs: comment: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - uses: actions/download-artifact@v4 with: name: profile-metrics path: /tmp/metrics/ github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} - name: Install hotpath-utils CLI run: cargo install --path crates/hotpath \ --bin hotpath-utils --features=utils - name: Post PR comment env: GH_TOKEN: ${{ github.token }} run: | set -euo pipefail export GITHUB_BASE_REF=$(cat /tmp/metrics/base_ref.txt) export GITHUB_HEAD_REF=$(cat /tmp/metrics/head_ref.txt) hotpath-utils profile-pr \ --head-metrics /tmp/metrics/head_timing.json \ --base-metrics /tmp/metrics/base_timing.json \ --github-token "$GH_TOKEN" \ --pr-number "$(cat /tmp/metrics/pr_number.txt)" \ --benchmark-id "timing" ``` -------------------------------- ### Preparing and Recording with samply Source: https://hotpath.rs/sampling_comparison Build the CPU-bound example with the 'profiling' profile and then use samply record to capture CPU performance data. This prepares for comparison with the hotpath report. ```bash cargo build --example profile_cpu --profile profiling samply record ./target/profiling/examples/profile_cpu ``` -------------------------------- ### Running Samply Profiling Source: https://hotpath.rs/sampling_comparison Commands to build the Rust example and then record profiling data using the samply tool. ```bash cargo build --example profile_blocking_io --profile profiling samply record ./target/profiling/examples/profile_blocking_io ``` -------------------------------- ### Launch hotpath TUI Source: https://hotpath.rs/ Launch the hotpath TUI after installing it with auto-instrumentation enabled. This will display real-time performance metrics of the TUI itself. ```bash hotpath ``` -------------------------------- ### hotpath Profiling Report for CPU-Bound Example Source: https://hotpath.rs/sampling_comparison The report shows the execution duration of functions, including calls, average time, P95, total time, and percentage of total time. It details the performance breakdown for main, heavy_work, and light_work. ```text [hotpath] timing - Execution duration of functions. profile_cpu::main: 210.02ms +-------------------------+-------+-----------+-----------+-----------+---------+ | Function | Calls | Avg | P95 | Total | % Total | +-------------------------+-------+-----------+-----------+-----------+---------+ | profile_cpu::main | 1 | 209.92 ms | 209.98 ms | 209.92 ms | 100.00% | +-------------------------+-------+-----------+-----------+-----------+---------+ | profile_cpu::heavy_work | 1000 | 169.91 µs | 254.72 µs | 169.91 ms | 80.94% | +-------------------------+-------+-----------+-----------+-----------+---------+ | profile_cpu::light_work | 1000 | 38.21 µs | 51.26 µs | 38.21 ms | 18.20% | +-------------------------+-------+-----------+-----------+-----------+---------+ ``` -------------------------------- ### Running Hotpath Profiling Source: https://hotpath.rs/sampling_comparison Command to compile and run the Rust example with the hotpath profiler enabled. This generates a profiling report. ```bash cargo run --example profile_blocking_io --features hotpath --profile profiling ``` -------------------------------- ### Install hotpath CLI with TUI and auto-instrumentation Source: https://hotpath.rs/ Install the hotpath CLI with features enabled for the TUI and auto-instrumentation. This allows you to profile the TUI process itself. ```bash cargo install hotpath --features='tui,hotpath,hotpath-alloc' --version '^0.16.1' ``` -------------------------------- ### Install Hotpath TUI Source: https://hotpath.rs/profiling_modes Install the Hotpath TUI (Terminal User Interface) using Cargo. This enables the live dashboard mode for monitoring application performance in real-time. ```bash cargo install hotpath --features=tui ``` -------------------------------- ### Hotpath Performance Summary Output Source: https://hotpath.rs/functions This is an example of the performance summary output generated by hotpath when the `hotpath` feature is enabled. ```text [hotpath] Performance summary from basic::main (Total time: 122.13ms): +-----------------------+-------+---------+---------+----------+---------+ | Function | Calls | Avg | P99 | Total | % Total | +-----------------------+-------+---------+---------+----------+---------+ | basic::async_function | 100 | 1.16ms | 1.20ms | 116.03ms | 95.01% | +-----------------------+-------+---------+---------+----------+---------+ | custom_block | 100 | 17.09µs | 39.55µs | 1.71ms | 1.40% | +-----------------------+-------+---------+---------+----------+---------+ | basic::sync_function | 100 | 16.99µs | 35.42µs | 1.70ms | 1.39% | +-----------------------+-------+---------+---------+----------+---------+ ``` -------------------------------- ### CPU-Bound Example with hotpath Instrumentation Source: https://hotpath.rs/sampling_comparison This Rust code defines two CPU-bound functions, heavy_work and light_work, both annotated with #[hotpath::measure]. The main function calls these in a loop. Use the --features=hotpath flag to enable hotpath profiling. ```rust #[hotpath::measure] fn heavy_work(iterations: u32) -> u64 { let mut result: u64 = 1; for i in 0..iterations { result = result.wrapping_mul(black_box(i as u64).wrapping_add(7)); result ^= result >> 3; } result } #[hotpath::measure] fn light_work(iterations: u32) -> u64 { let mut result: u64 = 0; for i in 0..iterations { result = result.wrapping_add(black_box(i as u64)); } result } #[hotpath::main] fn main() { let mut total: u64 = 0; for _ in 0..1000 { total = total.wrapping_add(heavy_work(500_000)); total = total.wrapping_add(light_work(100_000)); } } ``` -------------------------------- ### Run Hotpath TUI Dashboard Source: https://hotpath.rs/profiling_modes Launch the Hotpath TUI dashboard from your terminal. This command starts the interactive interface that will display live performance metrics once your instrumented application is running. ```bash hotpath console ``` -------------------------------- ### Enable tokio Feature in Cargo.toml Source: https://hotpath.rs/tokio_runtime Add the hotpath crate with the 'tokio' feature enabled to your Cargo.toml file to start collecting Tokio runtime metrics. ```toml [dependencies] hotpath = { version = "0.16.1", features = ["tokio"] } ``` -------------------------------- ### Verify samply version Source: https://hotpath.rs/cpu_profiling Check the installed version of samply. hotpath-rs is tested with version 0.13.x. ```bash samply --version ``` -------------------------------- ### Build HotpathGuard with Custom Settings Source: https://hotpath.rs/profiling_modes Use `HotpathGuardBuilder` to manually control the profiling guard's lifetime and configuration. This allows starting profiling later, stopping earlier, or executing custom logic before shutdown. ```rust use std::time::Duration; #[hotpath::measure] fn example_function() { std::thread::sleep(Duration::from_millis(10)); } fn main() { let guard = hotpath::HotpathGuardBuilder::new("my_program") .percentiles(&[95.0, 99.0]) .limit(10) .functions_limit(20) .format(hotpath::Format::Table) .build(); example_function(); // Dropping the guard shuts down profiling and writes the report. drop(guard); // This exits immediately, so #[hotpath::main] would not generate a report. std::process::exit(1); } ``` -------------------------------- ### Build and run with profiling features Source: https://hotpath.rs/cpu_profiling Build and run your project using the custom 'profiling' profile and the 'hotpath-cpu' feature. This will generate a CPU usage report. ```bash cargo run --features='hotpath,hotpath-alloc,hotpath-cpu' --profile profiling ``` -------------------------------- ### Add MCP Server (With Auth) Source: https://hotpath.rs/mcp Connect to an MCP server with an authentication token. The 'Authorization' header is included in the configuration. ```bash claude mcp add --transport http hotpath http://localhost:6771/mcp --header "Authorization: your-secret-token" ``` ```json "mcpServers": { "hotpath": { "type": "http", "url": "http://localhost:6771/mcp", "headers": { "Authorization": "your-secret-token" } } } ``` -------------------------------- ### Run Head Alloc Benchmark (Allocation) Source: https://hotpath.rs/github_ci Configures and runs a benchmark for memory allocation, outputting results in JSON format. ```yaml - name: Head alloc benchmark (alloc) env: HOTPATH_OUTPUT_FORMAT: json HOTPATH_OUTPUT_PATH: /tmp/metrics/head_alloc.json run: cargo run --release --example benchmark_alloc --features='hotpath,hotpath-alloc' ``` -------------------------------- ### Configure `#[hotpath::main]` Macro Parameters Source: https://hotpath.rs/functions The `#[hotpath::main]` macro supports several parameters to customize the profiling report, including percentiles, output format, function limit, output path, and report sections. ```rust /* * `percentiles = [50, 95, 99]` - Custom percentiles to display (defaults to `[95]`) * `format = "json"` - Output format `"table"`, `"json"`, `"json-pretty"`, `"none"` (defaults to `table`) * `limit = 20` - Maximum number of functions to display (default: `15`, `0` = show all) * `output_path = "report.json"` - Filesystem path for profiling reports. If not set, the report is written to `stdout`. Can be overridden by `HOTPATH_OUTPUT_PATH`; on Unix, set that env var to `/dev/stdout` or `/dev/stderr` to redirect to the standard streams. * `report = "functions-timing,channels"` - Comma-separated sections to include: `functions-timing`, `functions-alloc`, `channels`, `streams`, `futures`, `threads`, `debug`, or `all` (overridden by `HOTPATH_REPORT` env var) */ ``` -------------------------------- ### Async File Creation and Reading in Rust Source: https://hotpath.rs/sampling_comparison This Rust program demonstrates concurrent file creation and reading using async Tokio I/O. It writes large files in chunks and then reads them back into memory. Ensure Tokio and Hotpath are set up as dependencies. ```rust use std::fs::File; use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; use futures::future::join_all; const FILE_SIZE: usize = 20 * 1024 * 1024; // 20 MB const CHUNK_SIZE: usize = 8 * 1024; // 8 KB const NUM_FILES: usize = 5; #[hotpath::measure] async fn create_file(path: &str) { let mut file = File::create(path).await.expect("create"); let buf = vec![0xABu8; CHUNK_SIZE]; for _ in 0..(FILE_SIZE / CHUNK_SIZE) { file.write_all(&buf).await.expect("write"); } file.sync_all().await.expect("sync"); } #[hotpath::measure] async fn read_file(path: &str) -> Vec { let file = File::open(path).await.expect("open"); let mut reader = tokio::io::BufReader::new(file); let mut data = Vec::with_capacity(FILE_SIZE); reader.read_to_end(&mut data).await.expect("read"); data } #[tokio::main(flavor = "current_thread")] #[hotpath::main] async fn main() { let paths: Vec = (0..NUM_FILES) .map(|i| format!("/tmp/hotpath_async_{i}.bin")) .collect(); let path_refs: Vec<&str> = paths.iter().map(|s| s.as_str()).collect(); let futures: Vec<_> = path_refs.iter().map(|p| create_file(p)).collect(); join_all(futures).await; let futures: Vec<_> = path_refs.iter().map(|p| read_file(p)).collect(); join_all(futures).await; for path in &paths { tokio::fs::remove_file(path).await.ok(); } } ``` -------------------------------- ### Run Head Noop Benchmark (Timing) Source: https://hotpath.rs/github_ci Configures and runs a benchmark for function timing, outputting results in JSON format. ```yaml - name: Head noop benchmark (timing) env: HOTPATH_OUTPUT_FORMAT: json HOTPATH_OUTPUT_PATH: /tmp/metrics/head_timing.json run: cargo run --release --example benchmark_noop --features='hotpath' ``` -------------------------------- ### Install hotpath CLI without auto-profiling features Source: https://hotpath.rs/ Reinstall the hotpath CLI without auto-profiling features. This is necessary to profile other programs after using the auto-instrumentation mode. ```bash cargo install hotpath --features='tui' --version '^0.16.1' ``` -------------------------------- ### #[hotpath::main] macro Source: https://hotpath.rs/functions The `#[hotpath::main]` attribute macro initializes the background measurement processing. It supports several parameters to customize the profiling output. ```APIDOC ## `#[hotpath::main]` macro Attribute macro that initializes the background measurement processing when applied. Supports parameters: * `percentiles = [50, 95, 99]` - Custom percentiles to display (defaults to `[95]`) * `format = "json"` - Output format `"table"`, `"json"`, `"json-pretty"`, `"none"` (defaults to `table`) * `limit = 20` - Maximum number of functions to display (default: `15`, `0` = show all) * `output_path = "report.json"` - Filesystem path for profiling reports. If not set, the report is written to `stdout`. Can be overridden by `HOTPATH_OUTPUT_PATH`; on Unix, set that env var to `/dev/stdout` or `/dev/stderr` to redirect to the standard streams. * `report = "functions-timing,channels"` - Comma-separated sections to include: `functions-timing`, `functions-alloc`, `channels`, `streams`, `futures`, `threads`, `debug`, or `all` (overridden by `HOTPATH_REPORT` env var) ``` -------------------------------- ### Run Benchmark (Before) Source: https://hotpath.rs/benchmarks Executes the cargo run command to generate performance metrics for the 'before' state. Sets the output path and format for the benchmark results. ```bash HOTPATH_OUTPUT_PATH=tmp/before.txt HOTPATH_OUTPUT_FORMAT=json \ cargo run --features='hotpath,hotpath-alloc' ``` -------------------------------- ### Comparison of Hotpath and Samply Profiling Results Source: https://hotpath.rs/sampling_comparison This table compares the performance metrics for `create_file` and `read_file` functions as reported by Hotpath and Samply, highlighting significant differences in reported percentages. ```text +-------------------------------+-----------+-----------+ | Function | hotpath | samply | +-------------------------------+-----------+-----------+ | profile_async_io::create_file | ~410% | ~45% | | profile_async_io::read_file | ~35% | ~8% | +-------------------------------+-----------+-----------+ ``` -------------------------------- ### Build with tokio_unstable for Additional Metrics Source: https://hotpath.rs/tokio_runtime To collect advanced, unstable Tokio runtime metrics, build your project with the `tokio_unstable` configuration flag and the `hotpath` feature. ```bash RUSTFLAGS="--cfg tokio_unstable" cargo run --features='hotpath' ``` -------------------------------- ### Compare Benchmark Results Source: https://hotpath.rs/benchmarks Compares two JSON benchmark files ('before' and 'after') using the hotpath-utils compare command. This generates a table showing performance metric differences. ```bash hotpath-utils compare \ --before-json-path tmp/before.txt \ --after-json-path tmp/after.txt ``` -------------------------------- ### View CPU profiling results Source: https://hotpath.rs/cpu_profiling The output includes a table of function samples and their percentage of total CPU time. It also provides a command to load an interactive report. ```text +------------------------+---------+---------+ | Function | Samples | % Total | +------------------------+---------+---------+ | cpu_basic::sync_work | 1915914 | 56.13% | +------------------------+---------+---------+ | cpu_basic::async_sleep | 14056 | 0.41% | +------------------------+---------+---------+ | cpu_basic::sync_alloc | 1581 | 0.05% | +------------------------+---------+---------+ samply load /tmp/hotpath/61089-1778083683167502000/hp.json.gz ``` -------------------------------- ### Initialize hotpath Tokio Runtime Monitoring with Explicit Handle Source: https://hotpath.rs/tokio_runtime If you are not within a Tokio context that provides `Handle::current()`, you can pass an explicit handle to the `tokio_runtime!()` macro. ```rust let handle = tokio::runtime::Handle::current(); hotpath::tokio_runtime!(&handle); ``` -------------------------------- ### Initialize hotpath Tokio Runtime Monitoring Source: https://hotpath.rs/tokio_runtime Call the `tokio_runtime!()` macro within your async main function to spawn a background thread for collecting Tokio runtime metrics. This requires the `#[tokio::main]` and `#[hotpath::main]` attributes. ```rust #[tokio::main] #[hotpath::main] async fn main() { hotpath::tokio_runtime!(); // ... } ``` -------------------------------- ### Enable Memory Usage Reporting Source: https://hotpath.rs/profiling_modes Combine the 'hotpath' and 'hotpath-alloc' features to include memory usage statistics in the performance report. This provides insights into memory allocation patterns. ```bash cargo run --features='hotpath,hotpath-alloc' ``` -------------------------------- ### Profile Functions with `#[hotpath::main]` and `#[hotpath::measure]` Source: https://hotpath.rs/functions Use `#[hotpath::measure]` to instrument functions for timing and memory measurements. Apply `#[hotpath::main]` to the entry point of your application to initialize measurement processing. Ensure `#[tokio::main]` is placed before `#[hotpath::main]` when using Tokio. ```rust #[hotpath::measure] fn sync_function(sleep: u64) { std::thread::sleep(Duration::from_nanos(sleep)); } #[hotpath::measure] async fn async_function(sleep: u64) { tokio::time::sleep(Duration::from_nanos(sleep)).await; } // When using with tokio, place the #[tokio::main] first #[tokio::main] #[hotpath::main] async fn main() { for i in 0..100 { // Measured functions will automatically send metrics sync_function(i); async_function(i * 2).await; // Measure code blocks with static labels hotpath::measure_block!("custom_block", { std::thread::sleep(Duration::from_nanos(i * 3)) }); } } ``` -------------------------------- ### Hotpath Profiling Report Source: https://hotpath.rs/sampling_comparison Sample output from the hotpath profiler, showing function call counts, average, P95, and total execution times for the blocking I/O operations. ```text profile_blocking_io::main: 18.23ms +---------------------------------------+-------+-----------+----------+----------+---------+ | Function | Calls | Avg | P95 | Total | % Total | +---------------------------------------+-------+-----------+----------+----------+---------+ | profile_blocking_io::main | 1 | 18.10 ms | 18.10 ms | 18.10 ms | 100.00% | +---------------------------------------+-------+-----------+----------+----------+---------+ | profile_blocking_io::create_test_file | 1 | 12.99 ms | 12.99 ms | 12.99 ms | 71.77% | +---------------------------------------+-------+-----------+----------+----------+---------+ | profile_blocking_io::read_file | 5 | 956.59 µs | 1.26 ms | 4.78 ms | 26.42% | +---------------------------------------+-------+-----------+----------+----------+---------+ ``` -------------------------------- ### Configure `#[hotpath::measure]` Macro Parameters Source: https://hotpath.rs/functions The `#[hotpath::measure]` macro allows for logging return values, setting custom labels, and specifying the implementation type for methods within `impl` blocks. ```rust #[hotpath::measure(log = true)] fn compute() -> i32 { // The result value will be logged in TUI console 42 } #[hotpath::measure(label = "db_query")] fn fetch_user(id: u64) { /* ... */ } struct Worker; impl Worker { #[hotpath::measure(impl_type = "Worker")] fn run(&self) { /* ... */ } } ``` -------------------------------- ### Instrument Tokio MPSC Channel Creation Source: https://hotpath.rs/futures Wraps channel creation to automatically track performance metrics and data flow. Use this when you need to monitor message throughput and latency for Tokio MPSC channels. ```rust use tokio::sync::mpsc; #[tokio::main] #[hotpath::main] async fn main() { // Create and instrument a channel in one step let (tx, mut rx) = hotpath::channel!(mpsc::channel::(100)); // Use the channel exactly as before tx.send("Hello".to_string()).await.unwrap(); let msg = rx.recv().await.unwrap(); } ``` -------------------------------- ### Basic Function Instrumentation Source: https://hotpath.rs/cpu_profiling This snippet shows the basic usage of the `measure` macro for a standalone function. This is the standard way to instrument functions for CPU profiling. ```rust impl Worker { #[hotpath::measure] fn run() { // ... } } ``` -------------------------------- ### Run Benchmark (After) Source: https://hotpath.rs/benchmarks Executes the cargo run command after checking out to a different commit to generate performance metrics for the 'after' state. Sets the output path and format for the benchmark results. ```bash HOTPATH_OUTPUT_PATH=tmp/after.txt HOTPATH_OUTPUT_FORMAT=json \ cargo run --features='hotpath,hotpath-alloc' ``` -------------------------------- ### Hotpath Profiling Results for Async I/O Source: https://hotpath.rs/sampling_comparison This table displays the profiling results generated by Hotpath for the asynchronous file I/O operations, showing function calls, average time, P95 latency, total time, and percentage of total time. ```text profile_async_io::main: 166.70ms +-------------------------------+-------+-----------+-----------+-----------+---------+ | Function | Calls | Avg | P95 | Total | % Total | +-------------------------------+-------+-----------+-----------+-----------+---------+ | profile_async_io::create_file | 5 | 137.05 ms | 150.60 ms | 685.26 ms | 411.65% | +-------------------------------+-------+-----------+-----------+-----------+---------+ | profile_async_io::main | 1 | 166.46 ms | 166.59 ms | 166.46 ms | 100.00% | +-------------------------------+-------+-----------+-----------+-----------+---------+ | profile_async_io::read_file | 5 | 11.70 ms | 11.80 ms | 58.51 ms | 35.14% | +-------------------------------+-------+-----------+-----------+-----------+---------+ ``` -------------------------------- ### Configure Global Limit for Reports Source: https://hotpath.rs/profiling_modes Use the `limit` attribute in the `#[hotpath::main]` macro to set a global cap on the number of items displayed in each report section. Set to 0 to display all items. ```rust // Global limit applies to all sections #[hotpath::main(limit = 10)] fn main() { /* ... */ } ``` -------------------------------- ### Configure Linux kernel for CPU profiling Source: https://hotpath.rs/cpu_profiling On Linux, adjust kernel parameters to allow samply to collect profiling data. These settings are temporary and reset on reboot. ```bash echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope echo 0 | sudo tee /proc/sys/kernel/kptr_restrict ``` -------------------------------- ### Interpreting Hotpath Performance Report Source: https://hotpath.rs/ The report provides metrics on function execution time, memory allocations, and thread usage. Analyze these to identify performance bottlenecks in your application. ```text [hotpath] 1.20s | timing, alloc, threads timing - Function execution time metrics. +------------------------------+-------+----------+----------+----------+---------+ | Function | Calls | Avg | P95 | Total | % Total | +------------------------------+-------+----------+----------+----------+---------+ | docs_example::main | 1 | 1.20 s | 1.20 s | 1.20 s | 100.00% | +------------------------------+-------+----------+----------+----------+---------+ | docs_example::async_function | 1000 | 1.15 ms | 1.20 ms | 1.15 s | 96.10% | +------------------------------+-------+----------+----------+----------+---------+ | custom_block | 1000 | 18.13 µs | 31.71 µs | 18.13 ms | 1.51% | +------------------------------+-------+----------+----------+----------+---------+ | docs_example::sync_function | 1000 | 16.58 µs | 27.63 µs | 16.58 ms | 1.38% | +------------------------------+-------+----------+----------+----------+---------+ alloc - Cumulative allocations during each function call (including nested calls). +------------------------------+-------+---------+---------+---------+---------+ | Function | Calls | Avg | P95 | Total | % Total | +------------------------------+-------+---------+---------+---------+---------+ | docs_example::main | 1 | 63.0 KB | 63.1 KB | 63.0 KB | 100.00% | +------------------------------+-------+---------+---------+---------+---------+ | docs_example::sync_function | 1000 | 12 B | 12 B | 11.7 KB | 18.58% | +------------------------------+-------+---------+---------+---------+---------+ | custom_block | 1000 | 0 B | 0 B | 0 B | 0.00% | +------------------------------+-------+---------+---------+---------+---------+ | docs_example::async_function | 1000 | 0 B | 0 B | 0 B | 0.00% | +------------------------------+-------+---------+---------+---------+---------+ threads - Thread CPU and memory statistics. (RSS: 7.8 MB, Alloc: 2.1 MB, Dealloc: 304.3 KB, Diff: 1.8 MB, 5/10) +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ | Thread | Status | CPU% | Max% | CPU User | CPU Sys | CPU Total | Alloc | Dealloc | Diff | +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ | hp-functions | Sleeping | 1.8% | 1.8% | 0.018s | 0.001s | 0.019s | 1.8 MB | 291.3 KB | 1.5 MB | +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ | main | Sleeping | 6.3% | 6.3% | 0.123s | 0.070s | 0.193s | 367.8 KB | 9.9 KB | 357.9 KB | +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ | hp-threads | Running | 0.0% | 0.0% | 0.000s | 0.001s | 0.001s | 10.3 KB | 3.0 KB | 7.3 KB | +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ | hp-server | Sleeping | 0.0% | 0.0% | 0.000s | 0.001s | 0.001s | 1.8 KB | 56 B | 1.7 KB | +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ | thread_5 | Sleeping | - | - | 0.000s | 0.000s | 0.000s | 640 B | 24 B | 616 B | +--------------+----------+------+------+----------+---------+-----------+----------+----------+----------+ ``` -------------------------------- ### Enable MCP with Cargo Run Source: https://hotpath.rs/mcp Run your Rust program with the MCP feature enabled. Ensure 'hotpath', 'hotpath-alloc', and 'hotpath-mcp' features are included. ```bash cargo run --features='hotpath,hotpath-alloc,hotpath-mcp' ``` -------------------------------- ### Post Benchmark Comments with Unique IDs Source: https://hotpath.rs/github_ci Posts benchmark results to a PR comment using `hotpath-utils profile-pr`. Use distinct `--benchmark-id` values for each benchmark to ensure separate comments. ```bash hotpath-utils profile-pr \ --benchmark-id "noop" ... ``` ```bash hotpath-utils profile-pr \ --benchmark-id "alloc" ... ``` -------------------------------- ### Configure Per-Resource Limits Source: https://hotpath.rs/profiling_modes Override the global limit for specific sections using attributes like `functions_limit` and `channels_limit` within the `#[hotpath::main]` macro. This allows finer control over report detail. ```rust // Per-resource limits override the global limit #[hotpath::main(limit = 10, functions_limit = 20, channels_limit = 5)] fn main() { /* ... */ } ``` -------------------------------- ### Instrument all impl Functions with measure_all Source: https://hotpath.rs/cpu_profiling Apply the `measure_all` macro to an `impl` block to automatically attribute all symbols within it without needing individual configuration. ```rust #[hotpath::measure_all] impl Worker { fn run() { // ... } } ``` -------------------------------- ### Define profiling build profile in Cargo.toml Source: https://hotpath.rs/cpu_profiling Configure a custom build profile named 'profiling' in Cargo.toml that inherits from 'release' but includes debug symbols. ```toml [profile.profiling] inherits = "release" debug = true ``` -------------------------------- ### Generate JSON Report After Fixed Duration Source: https://hotpath.rs/profiling_modes Profile a long-running process by setting a shutdown duration in milliseconds. This ensures a report is generated after the specified time, useful for deterministic benchmarking or capturing metrics from processes that don't exit naturally. The output is directed to a JSON file. ```bash HOTPATH_SHUTDOWN_MS=10000 \ HOTPATH_OUTPUT_FORMAT=json \ HOTPATH_OUTPUT_PATH=tmp/report.json \ cargo run --features=hotpath ``` -------------------------------- ### Add MCP Server (No Auth) Source: https://hotpath.rs/mcp Connect to an MCP server using HTTP without authentication. This command adds the 'hotpath' server configuration. ```bash claude mcp add --transport http hotpath http://localhost:6771/mcp ``` ```json "mcpServers": { "hotpath": { "type": "http", "url": "http://localhost:6771/mcp" } } ``` -------------------------------- ### Debug values with hotpath::dbg! Source: https://hotpath.rs/debug Use `hotpath::dbg!` like `std::dbg!` to log values. Output is sent to the profiler's TUI, grouped by source location. Requires the `#[hotpath::main]` attribute. ```rust #[hotpath::main] fn main() { // Debug a single value - logs "3" hotpath::dbg!(1 + 2); // Debug multiple values hotpath::dbg!(foo(), bar()); } ``` -------------------------------- ### Instrumenting Futures-rs Bounded Channel Source: https://hotpath.rs/futures When instrumenting `futures::channel::mpsc` bounded channels, you must specify the `capacity` parameter as its API does not expose capacity after creation. ```rust use futures_channel::mpsc; // futures bounded channel - MUST specify capacity let (tx, rx) = hotpath::channel!(mpsc::channel::(10), capacity = 10); ``` -------------------------------- ### Instrument Rust Functions with Hotpath Macros Source: https://hotpath.rs/ Use `#[hotpath::measure]` to automatically collect metrics for synchronous and asynchronous functions. The `#[hotpath::main]` macro is required for the entry point. Ensure `#[tokio::main]` is placed before `#[hotpath::main]` if using Tokio. ```rust #[hotpath::measure] fn sync_function(sleep: u64) { std::thread::sleep(Duration::from_nanos(sleep)); let vec1 = vec![1, 2, 3]; std::hint::black_box(&vec1); // force mem allocation } #[hotpath::measure] async fn async_function(sleep: u64) { tokio::time::sleep(Duration::from_nanos(sleep)).await; } // When using with tokio, place the #[tokio::main] first #[tokio::main] #[hotpath::main] async fn main() { for i in 0..1000 { sync_function(i); async_function(i * 2).await; hotpath::measure_block!("custom_block", { std::thread::sleep(Duration::from_nanos(i * 3)) }); } } ``` -------------------------------- ### Customizing Channel Instrumentation Source: https://hotpath.rs/data_flow Add a custom label for easier identification in the TUI or enable message logging by passing `label` or `log = true` to the `hotpath::channel!` macro. Message logging requires the message type to implement `std::fmt::Debug`. ```rust // Custom label for easier identification in TUI let (tx, rx) = hotpath::channel!(mpsc::channel::(100), label = "worker_queue"); ``` ```rust // Enable message logging (requires std::fmt::Debug trait on message type) let (tx, rx) = hotpath::channel!(mpsc::channel::(100), log = true); ``` -------------------------------- ### Instrument Tokio Stream Creation Source: https://hotpath.rs/futures Instruments async streams to track performance metrics and items yielded. Use this to monitor data flow and processing within streams. ```rust use futures::stream::{self, StreamExt}; #[tokio::main] #[hotpath::main] async fn main() { // Create and instrument a stream in one step let s = hotpath::stream!(stream::iter(1..=100)); // Use it normally let items: Vec<_> = s.collect().await; } ``` -------------------------------- ### Measure all methods in an impl block with #[hotpath::measure_all] Source: https://hotpath.rs/functions Applies #[measure] to all methods within an impl block. Useful for bulk instrumentation. Note that for inherent impl blocks, the type segment is auto-injected for CPU sampling. ```rust #[hotpath::measure_all] impl Calculator { fn add(&self, a: u64, b: u64) -> u64 { a + b } fn multiply(&self, a: u64, b: u64) -> u64 { a * b } async fn async_compute(&self) -> u64 { /* ... */ } } ``` -------------------------------- ### Add hotpath to Cargo.toml Source: https://hotpath.rs/ Add hotpath as a dependency to your project's Cargo.toml file. Ensure to enable the necessary features for profiling. ```toml [dependencies] hotpath = "0.16.1" [features] hotpath = ["hotpath/hotpath"] hotpath-cpu = ["hotpath/hotpath-cpu"] hotpath-alloc = ["hotpath/hotpath-alloc"] ``` -------------------------------- ### Measure all functions in a module with #[hotpath::measure_all] Source: https://hotpath.rs/functions Applies #[measure] to all functions within a module. Useful for bulk instrumentation. This macro can also be used as an inner attribute `#![measure_all]` when Rust stabilizes the feature. ```rust #[hotpath::measure_all] mod math_operations { pub fn complex_calculation(x: f64) -> f64 { /* ... */ } pub async fn fetch_data() -> Vec { /* ... */ } } ``` -------------------------------- ### #[hotpath::measure] macro Source: https://hotpath.rs/functions The `#[hotpath::measure]` attribute macro instruments functions to send timing and memory measurements to the background processor. It offers parameters for logging, custom labels, and type implementation specification. ```APIDOC ## `#[hotpath::measure]` macro An attribute macro that instruments functions to send timing/memory measurements to the background processor. Parameters: * `log = true` - logs the result value when the function returns (requires `std::fmt::Debug` on return type) * `label = "name"` - replaces the full reported identifier (instead of `module_path::`). * `impl_type = "Type"` - inserts the enclosing type segment so the registered name becomes `module_path::::`. Use this for bare `#[hotpath::measure]` on a method inside an `impl` not covered by `measure_all`. Required for correct CPU sampling attribution under `hotpath-cpu` (see CPU profiling), since the demangled symbol contains the type segment. Example: ``` __ #[hotpath::measure(log = true)] fn compute() -> i32 { // The result value will be logged in TUI console 42 } #[hotpath::measure(label = "db_query")] fn fetch_user(id: u64) { /* ... */ } struct Worker; impl Worker { #[hotpath::measure(impl_type = "Worker")] fn run(&self) { /* ... */ } } ``` ``` -------------------------------- ### Set Allocation Metric for Reports Source: https://hotpath.rs/profiling_modes Control the primary metric for allocation reports by setting the `HOTPATH_ALLOC_METRIC` environment variable. Use `count` to sort by allocation count instead of bytes. ```bash HOTPATH_ALLOC_METRIC=count cargo run --features='hotpath,hotpath-alloc' ``` -------------------------------- ### hotpath::dbg! Source: https://hotpath.rs/debug Works like `std::dbg!` but sends debug output to the profiler instead of stderr. Logs are grouped by source location (file and line number) and viewable in the TUI. ```APIDOC ## `hotpath::dbg!` ### Description Works like `std::dbg!` but sends debug output to the profiler instead of stderr. Logs are grouped by source location (file and line number) and viewable in the TUI. ### Usage Example ```rust #[hotpath::main] fn main() { // Debug a single value - logs "3" hotpath::dbg!(1 + 2); // Debug multiple values hotpath::dbg!(foo(), bar()); } ``` ```