# span-timing
span-timing is a small, dependency-free crate for recording named scope durations in caller-owned counters.
It is useful for low-overhead instrumentation when a full profiling system is unnecessary or unavailable. `timing_entries!` associates a fixed set of named operations with an array of counters, and `timed_span!` measures a scope and delegates aggregation to each counter's `TimingCounter` implementation. The crate supplies `Counter` for count-and-total-tick measurements, while custom counter types can perform custom aggregation behavior.
## Usage
```rust
use span_timing::{Counter, timed_span, timing_entries};
// Set up the entries to record results for the spans we want to measure
timing_entries! {
pub enum Entry {
Func1,
Func2,
}
pub static COUNTERS: [Counter];
}
fn parse() {
let _timed_span_guard = timed_span!(Entry::Func1, COUNTERS);
// Code in the rest of this scope is timed.
}
```
## `no_std`
Disable the default `std` feature to use span-timing in `no_std` applications. This is supported on x86, x86_64, and aarch64 targets; other targets need the default `std` feature for its `Instant`-based clock fallback.
The built-in `Counter` struct requires 64-bit atomics, but custom `TimingCounter` types can use target-appropriate primitives.
## Acknowledgements
This work was initially created by [Igor Malovitsa](https://github.com/imlvts) in the [PathMap repository](https://github.com/adam-Vandervorst/pathMap/).
## Alternatives
[scopetime](https://crates.io/crates/scopetime) logs each scope's duration through the [`log`](https://crates.io/crates/log) facade. Prefer scopetime when individual measurements should flow through an application's existing logger and its configured output, filters, and sinks. Emitting a log record for every measured scope is much heavier-weight than updating in-memory atomic counters, so prefer span-timing when aggregate counts and elapsed ticks are sufficient.