hotpath-macros 0.2.0

Minimal performance profiler for Rust applications
Documentation

hotpath - track and profile Rust bottlenecks

Latest Version GH Actions

Report

A lightweight Rust performance measurement library with background processing and statistics aggregation. Instrument any function or code block to quickly find bottlenecks and profile calls with minimal overhead.

Features

  • Opt-in / zero cost when disabled (gate with a feature flag)
  • Zero-overhead profiling for functions and code blocks (bounded queue + background thread)
  • Stats per label: min, max, avg, total, calls, and % of total
  • Works in both sync and async code

Quick Start

Add to your Cargo.toml:

[dependencies]
hotpath = { version = "0.2", optional = true }

[features]
hotpath = ["dep:hotpath"]

Usage

use std::time::Duration;

#[cfg_attr(feature = "hotpath", hotpath::measure)]
fn sync_function() {
    std::thread::sleep(Duration::from_millis(100));
}

#[cfg_attr(feature = "hotpath", hotpath::measure)]
async fn async_function() {
    tokio::time::sleep(Duration::from_millis(150)).await;
}

#[tokio::main]
async fn main() {
    #[cfg(feature = "hotpath")]
    let _hotpath = hotpath::init!();

    // Measured functions will automatically send metrics
    sync_function();
    async_function().await;
    
    // Measure code blocks with static labels
    #[cfg(feature = "hotpath")]
    hotpath::measure_block!("sync_block", {
        std::thread::sleep(Duration::from_millis(100))
    });

    #[cfg(feature = "hotpath")]
    hotpath::measure_block!("async_block", {
        tokio::time::sleep(Duration::from_millis(150)).await;
    });
}

Run your program with a hotpath feature:

cargo run --features=hotpath

Output:

[hotpath] Performance Summary from basic::main (Total time: 512.97ms):
+-----------------------+-------+----------+----------+----------+----------+---------+
| Function              | Calls | Min      | Max      | Avg      | Total    | % Total |
+-----------------------+-------+----------+----------+----------+----------+---------+
| async_block           | 1     | 152.02ms | 152.02ms | 152.02ms | 152.02ms | 29.63%  |
+-----------------------+-------+----------+----------+----------+----------+---------+
| basic::async_function | 1     | 151.22ms | 151.22ms | 151.22ms | 151.22ms | 29.48%  |
+-----------------------+-------+----------+----------+----------+----------+---------+
| basic::sync_function  | 1     | 105.03ms | 105.03ms | 105.03ms | 105.03ms | 20.47%  |
+-----------------------+-------+----------+----------+----------+----------+---------+
| sync_block            | 1     | 104.38ms | 104.38ms | 104.38ms | 104.38ms | 20.35%  |
+-----------------------+-------+----------+----------+----------+----------+---------+

How It Works

  1. #[cfg_attr(feature = "hotpath", hotpath::measure)] - Proc-macro that wraps functions with timing code
  2. Background thread - Measurements are sent to a dedicated worker thread via bounded channel
  3. Non-blocking - Function execution continues immediately after sending measurement
  4. Statistics aggregation - Worker thread maintains running statistics for each function/code block
  5. Seamless cleanup - Performance summary displayed automatically when _hotpath guard is dropped

API

hotpath::init!()

Macro that initializes the background measurement processing thread. Returns a _hotpath guard that should be kept alive for the duration of measurements.

hotpath::measure_block!(label, expr)

Macro that measures the execution time of a code block with a static string label.

#[cfg_attr(feature = "hotpath", hotpath::measure)]

Attribute macro that instruments functions to send timing measurements to the background processor.