Skip to content

Commit 5609fa3

Browse files
committed
Update 0.7.1
1 parent 09fc538 commit 5609fa3

11 files changed

Lines changed: 142 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@
1111
## [Unreleased]
1212

1313

14+
<br>
15+
16+
## [0.7.1] - 2025-08-30
17+
### Added
18+
- Optional `trace` feature providing lightweight internal trace hooks for debugging overhead.
19+
- Crate-private `trace::record_event()`; zero cost when feature is off.
20+
- Wired into `Watch::record()` fast/slow paths behind `cfg(feature = "trace")`.
21+
22+
### Fixed
23+
- Eliminated `dead_code` warnings for `HistBackend` by gating the module behind `collector + metrics` in `src/lib.rs`.
24+
- Removed an incorrect public `trace!` macro to avoid unresolved symbol/API surface growth.
25+
26+
### Maintenance
27+
- Macro forward-compatibility: accepted optional trailing commas across timing/benchmark macros.
28+
29+
1430
<br>
1531

1632
## [0.7.0] - 2025-08-30
@@ -251,7 +267,8 @@ Initial pre-dev release for backup.
251267

252268

253269

254-
[Unreleased]: https://github.com/jamesgober/rust-benchmark/compare/v0.7.0...HEAD
270+
[Unreleased]: https://github.com/jamesgober/rust-benchmark/compare/v0.7.1...HEAD
271+
[0.7.1]: https://github.com/jamesgober/rust-benchmark/compare/v0.7.0...v0.7.1
255272
[0.8.0]: https://github.com/jamesgober/rust-benchmark/compare/v0.7.0...v0.8.0
256273
[0.7.0]: https://github.com/jamesgober/rust-benchmark/compare/v0.6.0...v0.7.0
257274
[0.6.0]: https://github.com/jamesgober/rust-benchmark/compare/v0.5.8...v0.6.0

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#╚═══════════╩══════════════════════════════════╩════════════╝
1111
[package]
1212
name = "benchmark"
13-
version = "0.7.0"
13+
version = "0.7.1"
1414
edition = "2021"
1515

1616
# Minimum Supported Rust Version (MSRV)
@@ -62,6 +62,7 @@ default = ["benchmark", "collector"] # Turn-key dev: timing
6262
benchmark = ["std"] # Enable real timing
6363
collector = ["std"] # Collector + histogram
6464
metrics = ["collector"] # Watch/Timer production metrics
65+
trace = ["std"] # Optional lightweight trace hooks (no-op when disabled)
6566

6667
# Precision backends
6768
high-precision = ["collector"] # Swap to high-precision histogram backend

README.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Add this to your `Cargo.toml`:
111111

112112
```toml
113113
[dependencies]
114-
benchmark = "0.7.0"
114+
benchmark = "0.7.1"
115115
```
116116

117117
<br>
@@ -123,7 +123,7 @@ benchmark = "0.7.0"
123123
[dependencies]
124124

125125
# Enables Production & Development.
126-
benchmark = { version = "0.7.0", features = ["standard"] }
126+
benchmark = { version = "0.7.1", features = ["standard"] }
127127
```
128128

129129
<br>
@@ -134,7 +134,7 @@ Enable production observability using `Watch`/`Timer` or the `stopwatch!` macro.
134134
Cargo features:
135135
```toml
136136
[dependencies]
137-
benchmark = { version = "0.7.0", features = ["std", "metrics"] }
137+
benchmark = { version = "0.7.1", features = ["std", "metrics"] }
138138
```
139139

140140
Record with `Timer` (auto-record on drop):
@@ -169,7 +169,7 @@ assert!(watch.snapshot()["render"].count >= 1);
169169
```toml
170170
[dependencies]
171171
# Disable default features for true zero-overhead
172-
benchmark = { version = "0.7.0", default-features = false }
172+
benchmark = { version = "0.7.1", default-features = false }
173173
```
174174
<br>
175175

@@ -406,6 +406,23 @@ overhead::time_macro/time_macro_add
406406

407407
<hr>
408408

409+
<h2>MSRV &amp; SemVer Policy</h2>
410+
<ul>
411+
<li><b>MSRV</b>: 1.70+ (as indicated by the badge). We bump MSRV only in <b>minor</b> releases and document it in the changelog.</li>
412+
<li><b>SemVer</b>:
413+
<ul>
414+
<li>Patch (x.y.<b>z</b>): bug fixes, internal improvements, and documentation.</li>
415+
<li>Minor (x.<b>y</b>.z): new features and non-breaking API additions.</li>
416+
<li>Major (<b>x</b>.y.z): breaking changes only, announced in the changelog with migration notes.</li>
417+
</ul>
418+
</li>
419+
<li><b>Feature flags</b>: additive and stable. Disabled paths remain zero-cost.</li>
420+
<li><b>No unsafe</b> in hot paths; any future "unsafe" will be justified and tested.</li>
421+
<li><b>Docs.rs</b>: examples note required feature flags to avoid confusion.</li>
422+
</ul>
423+
424+
<hr>
425+
409426
<h2 align="center">
410427
DEVELOPMENT &amp; CONTRIBUTION
411428
</h2>

docs/API.md

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
Add this to your `Cargo.toml`:
7777
```toml
7878
[dependencies]
79-
benchmark = "0.7.0"
79+
benchmark = "0.7.1"
8080
```
8181

8282
<br>
@@ -97,7 +97,7 @@ Add this to your `Cargo.toml`:
9797
```toml
9898
[dependencies]
9999
# Disable default features for true zero-overhead
100-
benchmark = { version = "0.7.0", default-features = false }
100+
benchmark = { version = "0.7.1", default-features = false }
101101
```
102102

103103
<br>
@@ -134,6 +134,23 @@ Notes:
134134

135135
<br>
136136

137+
## Quickstart
138+
Minimal examples to get productive fast. See full examples below for more depth.
139+
140+
```rust
141+
// Benchmarking (default features)
142+
let (out, d) = benchmark::time!({ 2 + 2 });
143+
assert_eq!(out, 4);
144+
assert!(d.as_nanos() >= 0);
145+
146+
// Production metrics (features = ["metrics"])
147+
let w = benchmark::Watch::new();
148+
benchmark::stopwatch!(w, "op", { std::thread::sleep(std::time::Duration::from_millis(1)); });
149+
assert!(w.snapshot()["op"].count >= 1);
150+
```
151+
152+
<br>
153+
137154
## Types
138155

139156
### Duration
@@ -421,7 +438,7 @@ Provides production-friendly timing and percentile statistics with negligible ov
421438
Installation with feature:
422439
```toml
423440
[dependencies]
424-
benchmark = { version = "0.7.0", features = ["metrics"] }
441+
benchmark = { version = "0.7.1", features = ["metrics"] }
425442
```
426443

427444
### Watch
@@ -694,11 +711,18 @@ When compiled with `default-features = false` or without `benchmark`:
694711
- `benchmark!` executes once and returns `(Some(result), Vec::new())`.
695712
- `Collector` and `Stats` are `collector`-gated; if `collector` is disabled they are not available.
696713

714+
## Common Pitfalls
715+
- Ensure required features are enabled for copied snippets (`collector`, `metrics`).
716+
- Zero durations are valid; avoid rewriting them at collection time. Clamp only at presentation.
717+
- Tune histogram bounds near your SLOs for better percentile precision and lower memory.
718+
- Keep metric names low-cardinality and stable to reduce map contention.
719+
- Avoid holding your own locks across `await` inside timed regions.
720+
697721
### Best Practices: Handling 0ns in dashboards
698-
- Preserve fidelity in the data layer: zero durations are valid measurements for extremely fast operations.
699-
- Apply a visualization floor at presentation time only if necessary (e.g., show 1ns instead of 0ns) to avoid skewing aggregates.
700-
- Consider filtering 0ns when computing percentiles for SLO charts if they represent measurement granularity rather than business latency.
701-
- If you need to avoid zeros in histograms, clamp on export, not at collection: `max(value, 1)`. Keep raw storage exact for audits.
722+
- Preserve fidelity in the data layer: zero durations are valid measurements for extremely fast ops.
723+
- Apply a visualization floor only at presentation time if necessary.
724+
- Consider filtering 0ns when computing percentiles if they reflect timer granularity rather than business latency.
725+
- If you must avoid zeros in histograms, clamp on export (`max(value, 1)`), not at collection.
702726

703727
<br>
704728

docs/features/BENCHMARK.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ The <b>benchmark</b> feature provides a lightweight, statistically-sound toolkit
5555
[dependencies]
5656

5757
# Benchmark is enabled by default.
58-
benchmark = "0.7.0"
58+
benchmark = "0.7.1"
5959

6060
# or enable benchmark explicitly.
61-
benchmark = { version = "0.7.0", features = ["benchmark"]}
61+
benchmark = { version = "0.7.1", features = ["benchmark"]}
6262
```
6363
> ⚙️ Add directly to your `Cargo.toml`.
6464

docs/features/METRICS.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ The <b>metrics</b> feature provides production-grade latency metrics with near-z
5050
### Manual installation:
5151
```toml
5252
[dependencies]
53-
benchmark = { version = "0.5.8", features = ["metrics"] }
53+
benchmark = { version = "0.7.1", features = ["metrics"] }
5454
```
5555
> ⚙️ Add directly to your `Cargo.toml`.
5656
@@ -87,6 +87,20 @@ fn main() {
8787
}
8888
```
8989

90+
<br>
91+
<hr>
92+
<br>
93+
94+
## Accuracy and Performance Trade-offs
95+
96+
- **Bounds selection**: Choose `lowest` and `highest` close to your SLOs. Tighter ranges improve percentile precision and reduce memory.
97+
- **Input clamping**: `Watch::record()` clamps to histogram bounds. Percentile queries clamp `q` to [0.0, 1.0]. This avoids panics and yields sane results for out-of-range inputs.
98+
- **Precision vs memory**: The built-in histogram is fixed-size and optimized for lock-free recording; memory usage grows with the configured range. Tune bounds rather than sampling frequency.
99+
- **Contention**: Recording is lock-free; map access for new metric names may take a write lock once. Keep metric names stable and low-cardinality. Consider sharding hot metrics and merging snapshots offline if necessary.
100+
- **Snapshots**: Percentiles are computed from cloned histograms outside locks to minimize contention. Snapshot costs scale with the number of metrics.
101+
- **Zero durations**: Some platforms can return 0ns for extremely fast ops; this is preserved. Clamp in presentation if needed, not at collection.
102+
- **Tracing hooks (optional)**: Enabling the `trace` feature adds lightweight, gated logging for hot-path events to aid debugging overhead; it is zero-cost when disabled.
103+
90104
### Ergonomic scoped timing with `stopwatch!`
91105
```rust
92106
use benchmark::{stopwatch, Watch};

docs/features/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Notes:
7676
#### Manual installation:
7777
```toml
7878
[dependencies]
79-
benchmark = "0.7.0" # default features enabled (benchmark + collector)
79+
benchmark = "0.7.1" # default features enabled (benchmark + collector)
8080
```
8181
> ⚙️ Add directly to your `Cargo.toml`.
8282
@@ -104,7 +104,7 @@ Enables the [**`benchmark`**](./BENCHMARK.md) feature.
104104
#### Manual installation:
105105
```toml
106106
[dependencies]
107-
benchmark = { version = "0.7.0", features = ["metrics"]}
107+
benchmark = { version = "0.7.1", features = ["metrics"]}
108108
```
109109

110110
#### Terminal
@@ -128,7 +128,7 @@ cargo add benchmark -F metrics
128128
#### Manual installation:
129129
```toml
130130
[dependencies]
131-
benchmark = { version = "0.7.0", default-features = false }
131+
benchmark = { version = "0.7.1", default-features = false }
132132
```
133133
> ⚙️ Add directly to your `Cargo.toml`.
134134

0 commit comments

Comments
 (0)