benchmark 0.8.0

Nanosecond-precision benchmarking for dev, testing, and production. Zero-overhead core timing when disabled; optional std-powered collectors and zero-dependency metrics (Watch/Timer) for real service observability.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
name: CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1
  # For benchmark consistency
  CARGO_BUILD_JOBS: 2
  RUST_TEST_THREADS: 2

jobs:
  # Cross-platform build and test matrix
  build-test:
    name: Build & Test (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        rust: [stable]
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
          - os: macos-latest
            target: x86_64-apple-darwin
          - os: windows-latest
            target: x86_64-pc-windows-msvc

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: ${{ matrix.rust }}
          targets: ${{ matrix.target }}
          components: rustfmt, clippy

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-

      - name: Build (debug)
        run: cargo build --verbose

      - name: Build (release)
        run: cargo build --release --verbose

      - name: Run tests
        run: cargo test --workspace --verbose

      - name: Run tests (release mode)
        run: cargo test --workspace --release --verbose

  # Feature matrix testing
  feature-test:
    name: Feature Testing
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        features:
          - ""                               # no default features (no_std build)
          - "benchmark"                      # timing only
          - "collector"                      # collector + histogram
          - "metrics"                        # production metrics
          - "high-precision"                 # high-precision backend (collector implied)
          - "hdr"                             # external HDR backend (high-precision implied)
          - "metrics high-precision"         # metrics + high-precision
          - "metrics hdr"                    # metrics + hdr backend

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Test feature combination
        run: |
          echo "Testing with features: ${{ matrix.features }}"
          if [ -z "${{ matrix.features }}" ]; then
            cargo test --workspace --no-default-features
          else
            cargo test --workspace --no-default-features --features "${{ matrix.features }}"
          fi

  # Optimization-level matrix to catch codegen-sensitive issues
  opt-matrix:
    name: Opt-Level Matrix
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        opt: ["0", "1", "2", "3", "s", "z"]
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Test workspace (opt=${{ matrix.opt }})
        env:
          RUSTFLAGS: -C opt-level=${{ matrix.opt }}
        run: |
          echo "RUSTFLAGS=$RUSTFLAGS"
          cargo test --workspace -q

      - name: Test workspace all-features (opt=${{ matrix.opt }})
        env:
          RUSTFLAGS: -C opt-level=${{ matrix.opt }}
        run: |
          echo "RUSTFLAGS=$RUSTFLAGS"
          cargo test --workspace --all-features -q

  # Assembly inspection (artifacts for manual review)
  assembly:
    name: Assembly Inspection
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Build disabled (rlib)
        run: |
          cargo clean
          cargo build --release --lib --no-default-features
          cp target/release/libbenchmark.rlib libbenchmark_disabled.rlib || true

      - name: Build benchmark (rlib)
        run: |
          cargo clean
          cargo build --release --lib --features "benchmark"
          cp target/release/libbenchmark.rlib libbenchmark_enabled.rlib || true

      - name: Dump symbols and disassembly (GNU objdump)
        run: |
          set -e
          if command -v objdump >/dev/null 2>&1; then
            if [ -f libbenchmark_disabled.rlib ]; then
              objdump -t libbenchmark_disabled.rlib > symbols_disabled.txt || true
              objdump -d libbenchmark_disabled.rlib > disasm_disabled.txt || true
            fi
            if [ -f libbenchmark_enabled.rlib ]; then
              objdump -t libbenchmark_enabled.rlib > symbols_enabled.txt || true
              objdump -d libbenchmark_enabled.rlib > disasm_enabled.txt || true
            fi
          else
            echo "objdump not available, skipping"
          fi

      - name: Dump disassembly (LLVM objdump fallback)
        run: |
          if command -v llvm-objdump >/dev/null 2>&1; then
            if [ -f libbenchmark_disabled.rlib ]; then
              llvm-objdump -t libbenchmark_disabled.rlib > symbols_disabled_llvm.txt || true
              llvm-objdump -d libbenchmark_disabled.rlib > disasm_disabled_llvm.txt || true
            fi
            if [ -f libbenchmark_enabled.rlib ]; then
              llvm-objdump -t libbenchmark_enabled.rlib > symbols_enabled_llvm.txt || true
              llvm-objdump -d libbenchmark_enabled.rlib > disasm_enabled_llvm.txt || true
            fi
          else
            echo "llvm-objdump not available, skipping"
          fi

      - name: Upload assembly artifacts
        uses: actions/upload-artifact@v4
        with:
          name: assembly-artifacts
          path: |
            symbols_*.txt
            disasm_*.txt

  # Code quality checks
  quality:
    name: Code Quality
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Check formatting
        run: cargo fmt --all -- --check

      - name: Clippy analysis
        run: |
          cargo clippy --workspace --all-features --all-targets -- -D warnings
          cargo clippy --workspace --no-default-features --all-targets -- -D warnings

      # Commented out failing check
      # - name: Check for unused dependencies
      #   run: |
      #     cargo install cargo-machete
      #     cargo machete

  # Security audit
  security:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Install cargo-audit
        run: cargo install cargo-audit

      - name: Run security audit
        run: cargo audit

  # Zero-overhead verification
  zero-overhead:
    name: Zero Overhead Verification
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Build without benchmarking
        run: |
          cargo build --release --lib --no-default-features
          # For a library crate, check the size of the rlib file
          if [ -f target/release/libbenchmark.rlib ]; then
            mv target/release/libbenchmark.rlib target/release/libbenchmark_disabled.rlib
          else
            # Fallback: measure the target directory size
            du -sb target/release > disabled_size.txt
          fi

      - name: Build with benchmarking
        run: |
          cargo build --release --lib --features "benchmark"
          if [ -f target/release/libbenchmark.rlib ]; then
            mv target/release/libbenchmark.rlib target/release/libbenchmark_enabled.rlib
          else
            du -sb target/release > enabled_size.txt
          fi

      - name: Compare binary sizes
        run: |
          if [ -f target/release/libbenchmark_disabled.rlib ] && [ -f target/release/libbenchmark_enabled.rlib ]; then
            SIZE_DISABLED=$(stat -c%s target/release/libbenchmark_disabled.rlib 2>/dev/null || stat -f%z target/release/libbenchmark_disabled.rlib)
            SIZE_ENABLED=$(stat -c%s target/release/libbenchmark_enabled.rlib 2>/dev/null || stat -f%z target/release/libbenchmark_enabled.rlib)
            echo "Size without benchmarking: $SIZE_DISABLED bytes"
            echo "Size with benchmarking: $SIZE_ENABLED bytes"
            echo "Overhead: $((SIZE_ENABLED - SIZE_DISABLED)) bytes"
          else
            echo "Using directory size comparison as fallback"
            if [ -f disabled_size.txt ] && [ -f enabled_size.txt ]; then
              SIZE_DISABLED=$(cut -f1 disabled_size.txt)
              SIZE_ENABLED=$(cut -f1 enabled_size.txt)
              echo "Build size without benchmarking: $SIZE_DISABLED bytes"
              echo "Build size with benchmarking: $SIZE_ENABLED bytes"
              echo "Overhead: $((SIZE_ENABLED - SIZE_DISABLED)) bytes"
            fi
          fi

  # Documentation checks
  docs:
    name: Documentation
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Check documentation
        env:
          RUSTDOCFLAGS: -D warnings
        run: cargo doc --workspace --all-features --no-deps

      - name: Test documentation examples
        run: cargo test --workspace --all-features --doc

  # Build benchmark and examples across feature modes to catch regressions
  build-benchmark-examples:
    name: Build benchmark/examples (all feature modes)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-

      - name: Build default features
        run: |
          cargo build --benches -q
          cargo build --examples -q

      - name: Build all features
        run: |
          cargo build --benches --all-features -q
          cargo build --examples --all-features -q

      - name: Build no default features
        run: |
          cargo build --benches --no-default-features -q
          cargo build --examples --no-default-features -q

  # Performance benchmarks (only on main branch)
  benchmarks:
    name: Performance Benchmarks
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Run benchmarks
        run: |
          # Test zero-overhead claim
          echo "Testing zero-overhead when disabled..."
          cargo build --release --no-default-features
          cargo build --release --features "benchmark"
          
          # Run actual benchmarks if they exist
          if [ -d "benches" ]; then
            cargo bench --all-features -- --output-format bencher | tee output.txt
          else
            echo "No benchmarks found, skipping..."
          fi

      - name: Check benchmark results
        if: github.event_name == 'pull_request'
        run: |
          # Benchmark regression detection placeholder. Intended plan:
          # 1) Establish baselines in perf_baselines/*.json on main via a scheduled job.
          # 2) Compare current PR results against baselines with a small tolerance window.
          # 3) Fail the job if regressions exceed thresholds; otherwise, post a summary comment.
          echo "Benchmark results comparison step (baselines required)"

  # Memory safety checks with Miri (nightly)
  miri:
    name: Miri (Memory Safety)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Rust nightly with Miri
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: miri

      - name: Setup Miri
        run: cargo miri setup

      - name: Run Miri tests
        run: cargo miri test --test miri_ub --features "std"
        env:
          MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-symbolic-alignment-check

  # Minimum Supported Rust Version check
  msrv:
    name: MSRV Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install MSRV Rust (retry)
        shell: bash
        run: |
          set -euo pipefail
          MSRV=1.75.0
          echo "Installing Rust $MSRV with retry..."
          for attempt in 1 2 3; do
            if rustup toolchain install "$MSRV" -c rustfmt -c clippy; then
              break
            fi
            echo "rustup install attempt $attempt failed; retrying after backoff..."
            sleep $((10 * attempt))
          done
          rustup default "$MSRV"
          rustc --version

      # Regenerate Cargo.lock to ensure compatibility
      - name: Delete existing Cargo.lock
        run: rm -f Cargo.lock
        
      - name: Regenerate Cargo.lock with MSRV
        run: cargo generate-lockfile
        
      - name: Check MSRV compatibility (lib only, no default features)
        run: cargo check --lib --no-default-features

      - name: Check MSRV compatibility (lib with metrics)
        run: cargo check --lib --no-default-features --features "metrics"

      - name: Check MSRV compatibility (HDR backend)
        run: cargo check --lib --no-default-features --features "hdr"