Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Performance

These are local reference measurements, not CI thresholds.

Method

  • Reference host: kbench, Intel Core i7-6700HQ, 4 cores and 8 threads, 2.6 GHz, Linux x86_64, rustc 1.97.0. The benchmark process was pinned to one CPU.
  • Release build with a fixed fixture generator.
  • cargo bench -p adotenv --bench core --locked -- --sample-size 20 --measurement-time 2
  • The host was otherwise idle. Wall time is recorded; instruction counts are the stable CPU comparison for cross-library work.

Core workloads

Workload8 entries128 entries65,536 entries
parse6.29 us99.8 us62.4 ms
lookup index build136.6 ns2.36 us3.40 ms
indexed get, 64 keys195.8 ns1.63 us1.76 us
portability, 4 presets62.8 us1.09 ms745 ms
references507.6 ns7.94 us4.64 ms
resolve7.23 us173.9 us118.9 ms
sort3.19 us278.6 us161.1 ms
format normalize8.30 us135.8 us76.7 ms
native set10.4 us102.4 us61.7 ms
native batch8.33 us102.9 us63.6 ms

Document::get scans entries. For many lookups, build Document::lookup_index once. The index uses a compact open-addressed table with an ordered fallback for collision-heavy input.

Parser memory

One 65,536-entry document with a 1.8 MB source:

  • live after parse: 23.6 MB;
  • peak parse: 32.0 MB;
  • parse plus collected map: 4.6 MB live after the document is dropped.

Retained document memory is dominated by item and token metadata. Values-only loading avoids the document entirely.

Loading memory

One 65,536-entry file on a release build:

ProfilePeakRetained
Default47.7 MB28.0 MB
LoadOptions::full57.4 MB37.7 MB
Values only11.2 MB10.0 MB

The default keeps values, shared-file origins and raw tokens. Reports add entry, override, repeat and skipped vectors. Values-only loading projects values while parsing and retains no document or provenance.

The default profile now stores value, origin and raw-token data in one record per key. This removes two per-key maps from the retained loader.

Budgets

The comparison harness is the source of these budgets. Reference results are recorded on the kbench host. Run the full check with:

python3 scripts/compare.py --check-budgets
ProfileInstructionsPeak RSSRetained RSS
adotenv parse260Mnot budgeted29 MB
adotenv parse + values400M12 MB12 MB
adotenv parse + map335Mnot budgeted16 MB
values-only load400M13 MB11.5 MB
default load560M50 MB30 MB
full-report load750M60 MB40 MB

The parse-only binary budget is 500 KB. Wall time is recorded but not enforced because the shared host is too noisy for a hard threshold.

A release blocks above the instruction or memory budget until the regression is fixed or explicitly accepted. A wall-time result between 1.5x and 2x requires a repeat run and an explanation; above 2x blocks the release.

Diff and matrix

For three 65,536-entry files:

  • streaming two-file diff with indexed comparison: about 73.3 MB peak and 0.6 s;
  • matrix diff with compact incremental rows: about 103.0 MB peak and 0.8 s.

Matrix output retains one row per key because every column is needed. Two-file diff streams candidates and buffers output until all candidates validate.

Comparison with other parsers

The closest comparison is adotenv::parse followed by collecting effective values. Other crates return maps or load into the environment directly.

Fixture: 65,536 compatible declarations, 1.8 MB source.

ImplementationInstructionsLive memoryPeak
adotenv parse272M23.6 MB32.0 MB
adotenv parse + map377M4.6 MB32.0 MB
dotenvy iterator + Vec373M5.0 MB15.7 MB
dotenv-compat parse307M9.5 MB18.6 MB
dotenv-ng input-only load406M7.9 MB20.4 MB
dotenv-parser map1,488M7.1 MB50.1 MB

adotenv retains more syntax than the other parsers, including spans, items and diagnostics. Values-only loading removes that overhead when it is not needed.

Budget

  • CI runs benchmark smoke only.
  • Compare repeated runs on the same host and toolchain.
  • A 1.5x deviation needs a repeat run and an explanation.
  • A 2x deviation blocks a release until it is explained or fixed.
  • Update this file when fixtures, compiler major version or methodology change.