profiling
A thin, backend-agnostic abstraction over instrumented Rust profilers like Puffin, Optick, and Tracy.
Repository Health
Technical Analysis
profiling is a very thin abstraction layer over instrumented profiling crates such as puffin, optick, tracy, and superluminal-perf. You annotate your code once with lightweight macros and attributes, then choose which profiler backend to enable at build time via cargo features — without changing any of your instrumentation.
This lets library and application authors add profiling scopes that impose zero cost when disabled, while letting the end user (or downstream binary) decide which profiler to actually capture with. It is widely used across the Rust game-dev and graphics ecosystem.
What You Get
- A backend-agnostic profiling API used through simple macros and attributes
- Support for Puffin, Optick, Tracy, and Superluminal backends selected via cargo features
- A #[profiling::function] attribute and scope!/finish_frame! macros
- Zero overhead when no profiler backend is enabled
- The ability for downstream binaries to choose the profiler without touching library code
Common Use Cases
- Instrumenting game engines and real-time apps with per-frame profiling scopes
- Adding optional profiling to a library without forcing a profiler on consumers
- Switching between Puffin, Tracy, and Optick backends without changing instrumentation
- Measuring hot paths in graphics and simulation code with named scopes
Under The Hood
Architecture - profiling is a Cargo workspace with the main profiling crate and a profiling-procmacros crate that implements the #[profiling::function] attribute. The core crate exposes macros (scope!, finish_frame!, register_thread!) that expand, under cfg feature gates, into the corresponding calls of whichever backend (puffin/optick/tracy/superluminal) is enabled, or into no-ops otherwise. A demo-puffin project shows an end-to-end integration.
Tech Stack - Written in Rust with a proc-macro companion crate; backends are pulled in only when their feature is active, keeping the default dependency footprint minimal. It relies on each backend crate’s own runtime for actual capture and visualization.
Code Quality - The project is mature and stable with a documented CHANGELOG, deny.toml for supply-chain checks, rustfmt config, screenshots demonstrating each backend, and a runnable demo. Its correctness is validated largely through real-world use across the graphics/game ecosystem rather than an extensive unit-test suite, since most logic is compile-time macro expansion.
API Design - The API is intentionally tiny and ergonomic: annotate a function or open a named scope and you are done. Feature-flag-driven backend selection means instrumentation is written once and reused, giving a very low learning curve, with the main subtlety being understanding each backend’s setup and network behavior.