commits
- Add individual optimization benchmarks for lavyek backend (baseline,
+inline, +cache, +inode, +all) in run_bench.sh, gen_chart_all.py,
and gen_readme_results.py
- Clean irmini_trace.json: remove spurious standard benchmark entries
(100B values with +cache names) that polluted the memory optims chart
- Remove --cache from trace replay section (now default in backends)
- Use consistent colors and order across all optimization charts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rerun individual optimization benchmarks (baseline, +inline, +cache,
+inode, +all) for both disk and memory backends with current code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The lavyek benchmark was running with cache=0 while disk/memory backends
benefited from the 100k LRU cache via Store.create. Fix the default to
cache=100_000 for consistency and rerun lavyek benchmarks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lavyek results are already included in irmini_inode.json which is
the file used by charts and README generation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Key improvements vs previous run:
- Irmini (memory) commits-20B: 71k -> 231k ops/s (3.2x)
- Irmini (memory) tezos replay: 71k -> 142k ops/s (2x, now beats irmin-lwt)
- Irmini (lavyek) commits-20B: 84k -> 204k ops/s (2.4x)
- Irmini (disk) commits-20B: 2k -> 32k ops/s (16x)
- All reads now >1M ops/s across backends
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass --value-size 20 to standard benchmarks so scenario names
are "commits-20B" etc., matching the README documentation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Title 20, scenario labels 13, bar values 9, legend 13, axis 14.
Reduce max chart width and adapt bar/gap sizing dynamically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Match irmin-pack's default. Users can pass ~cache:0 to disable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify gen_chart_all.py to always produce stable names like
chart_disk.svg instead of chart_disk_<timestamp>.svg. Remove the
timestamp CLI argument and the rename workarounds in callers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scenarios now always appear in the same order on charts as in the
README documentation: commits-20B, reads-20B, incremental-20B,
commits-10K, reads-10K, incremental-10K, concurrent, tezos.
Previously the order depended on the order of appearance in the
JSON result files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inlined contents (≤48 bytes) are stored directly in the parent node
and must always be included in proofs to preserve the node hash
during verification. The blinded nodes test now uses values larger
than the inline threshold (64 bytes) so they are stored as separate
blobs and can be properly blinded.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Buffer all writes during Tree.hash into a local list with a
read-through cache, then flush everything as a single write_batch
at the end of commit. This is especially beneficial for the disk
backend where each individual write triggers a WAL sync (fsync).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a node has no pending modifications (empty children map and
empty removed set) and already has a known hash (Inode or Lazy state),
return the existing hash directly without recursing, serializing,
or writing to the backend. This avoids redundant work during commit
for the large majority of tree nodes that are unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Irmin-pack has a built-in LRU cache for its content-addressable store.
Enable the equivalent cache for irmini trace replay benchmarks to
ensure a fair comparison. This avoids redundant backend reads during
tree navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace O(n) association lists with O(log n) Map.Make(String) for
children modifications and Set.Make(String) for removed entries.
This eliminates linear scans in navigate, add_at, remove, and
write_tree which were a bottleneck on large tree nodes (e.g. the
Tezos genesis commit with ~309k operations).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename chart SVGs from timestamped names to stable names (chart_disk.svg, etc.)
- Update README references accordingly
- run_bench.sh: remove crashing Irmin-Eio fiber sweep (only 1 fiber is stable),
add auto-generation of tezos_parallel.json from parallel results
- gen_readme_results.py: classify parallel tezos entries (12d×) as disk,
add parallel trace-replay bullet in disk analysis
- gen_chart_all.py: dynamic parallel variant detection via is_parallel_variant(),
dynamic color resolution for new parallel variant names
- Regenerate README from JSON results for consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show Irmini (lavyek) 12d×50kf at 5.1M ops/s and Irmin-Eio (pack) 12d×1f
at 205k ops/s alongside sequential tezos bars, using diagonal hatching to
distinguish parallel from sequential results.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Irmin-Eio (pack) achieves 1.9x speedup with 12 domains × 1 fiber on the
full 10310-commit Tezos trace (205k vs 107k ops/s). Limited by irmin-pack's
serialized batch mechanism. Irmin_mem is not domain-safe (removed from
parallel benchmarks). Documents the architectural contrast with irmini's
lock-free Lavyek backend (94x on same trace).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Irmin-Eio (PR #2149) supports multicore via Kcas hashtables, atomics,
and Eio.Mutex. Add trace_replay_irmin.ml with a Make(S) functor that
replays Tezos traces on any irmin KV store, both sequentially and in
parallel across domains × fibers.
Tested: 4d×2f gives 7x speedup on memory, 18x on pack (tree ops
run in parallel; only commits are serialized by batch mechanism).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single entry point to run all benchmarks and update README:
- 7 steps: irmini standard, optimizations, trace replay, parallel
scaling (14 fiber counts), irmin comparison + trace, charts, README
- gen_readme_results.py generates Results section from JSON files
- gen_chart_parallel.py now reads data from JSON (--json flag)
- Irmin trace replay automated when IRMIN_DIR is set
- Full run_bench.sh options documented in README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parallel trace replay across 12 domains with Lavyek backend achieves
5.1M ops/s (94x speedup) at 50k fibers/domain. Adds trace_replay_parallel.ml,
gen_chart_parallel.py, and documents results in bench README.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Lavyek backend is a proper reusable library, not just a benchmark
dependency. This creates the irmin-lavyek opam package with its own
public library, and updates benchmarks to use Irmin_lavyek.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align Backend_lavyek API with Backend.Disk and Backend.Memory by
extracting the generic create_with_hash and adding create_sha256.
The existing create function is kept as an alias for create_sha1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Prerequisites section to bench/README.md listing the irmin repo,
required branches, and trace file. Add trace replay commands for both
irmini and irmin. Fix run_all.sh to use current irmini branch instead
of hardcoding the inode branch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add documentation for the four backends (Memory, Disk, Lavyek, Git),
backend combinators (cached, readonly, layered), the three optimizations
(inline, cache, inode), and a link to benchmark results.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Run tezos trace replay with --store-type=pack for both irmin-lwt and
irmin-eio. Results show disk performance nearly identical to memory
thanks to LRU cache: Irmin-Lwt 135K ops/s, Irmin-Eio 83K ops/s.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Irmin-Lwt and Irmin-Eio pack-mem trace replay results to JSON files
so they appear in the memory backends chart alongside Irmini (memory).
Irmini (lavyek) tezos results appear in the disk chart. Removed the
separate tezos chart category since all backends are memory-based.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Run irmin's official tree.exe trace replay (pack-mem, no GC) on both
branches for comparison with irmini results:
- Irmin-Lwt (main): ~131K ops/s in 30.6s CPU
- Irmin-Eio (cuihtlauac): ~83K ops/s in 48.1s CPU
- Irmini (memory): 71K ops/s in 56.3s
- Irmini (lavyek): 68K ops/s in 58.8s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Modify bench_irmin4_main to run trace replay on each active backend
(memory, disk, lavyek) instead of hardcoded memory
- Add trace replay results: memory 71K ops/s, lavyek 68K ops/s
- Fix mislabeled "Irmini (disk) trace-replay" → was actually memory
- Disk backend too slow for trace replay (WAL fsync per write)
- Update README and regenerate charts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Irmini (disk) WAL+bloom results to disk backends table
- Update disk optimizations with WAL-based results (fsync bottleneck)
- Fix SVG chart references to current timestamp
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ocaml-wal off-by-one bug (block_remaining < header_size → <=) has
been fixed, allowing the disk backend to complete all scenarios.
New results:
- irmini_disk.json: 7 scenarios (commits, reads, incremental, concurrent)
- irmini_optims_disk.json: rerun with WAL+bloom backend (5 variants × 7 scenarios)
WAL fsync dominates write-heavy scenarios; inodes help commits (3x),
cache helps reads (10x for large objects).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use lavyek backend instead of disk (which crashes with
Eio_mutex.Poisoned). Add ?inode and ?name parameters to
bench_irmin4_lavyek.ml for optim variant support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite Results section with data from rerun benchmarks:
- Order: disk, memory, git, optims disk, optims memory, tezos replay
- All scenarios use 20B small values (below inlining threshold)
- trace-replay shown as scenario in disk chart
- Updated analysis to reflect new numbers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Charts now show all scenarios with matching names across the three
implementations, with correct colors (orange=Lwt, red=Eio, blue=Irmini).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use 20-byte values (below 48B inlining threshold) so small-value
scenarios actually test value inlining. All three implementations
now use identical parameters for fair comparison.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add fmt_size to both Irmin adapter bench_common.ml
- Use size-suffixed scenario names (commits-20B, reads-10K, etc.)
- Run each scenario twice (small + large values) like irmini
- Remove separate large-values scenario (now covered by dual-run)
This ensures all three implementations produce identically-named
scenarios so chart bars are grouped correctly for comparison.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename "Irmin-pack (eio)" to "Irmin-Eio (pack)", "Irmin-fs (disk)" to
"Irmin-Eio (fs)", "Irmin-git (disk)" to "Irmin-Eio (git)" so that
chart colors (red for Eio family) are applied correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove stale irmini_git.json (old scenario names), regenerate SVG
charts from current JSON results, and add chart images back to README.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fresh benchmark run on 2026-03-10 comparing:
- Irmin-Lwt (main branch): memory, pack, fs, git
- Irmin-Eio (cuihtlauac branch): memory, pack, fs, git
- Irmini (inode branch): memory, git
Key findings: irmini 4.5x faster on git commits (7.9k vs 1.8k ops/s)
with 13x less memory, 2.9x faster on incremental updates.
Tezos trace replay: 73K ops/sec over 10K commits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reads .repr trace files (IrmRepBT format) and replays recorded Tezos
operations (Checkout, Add, Remove, Copy, Find, Mem, Commit) on an
Irmini store. Uses the repr library for binary decoding.
New CLI options: --trace, --trace-commits, --trace-empty-blobs, --no-flatten
Tested on data4_10310commits.repr: 10310 commits, 4M ops in 55s (73K ops/sec).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detail what each benchmark does, what it measures, and which
optimizations it is sensitive to.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clarifies that these are adapters for the old Irmin (Lwt/Eio) benchmarks,
and consolidates all benchmark code under bench/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The monopampam versions of ocaml-bloom and ocaml-atp use Bloom.v and
Mst.find (not Bloom.create/Mst.get as in Thomas's standalone branch).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bloom.v → Bloom.create (API change in ocaml-bloom)
- PathSet → Path_set (typo in proof.ml)
- Atp.Mst.find → Atp.Mst.get (API rename in ocaml-atp)
- Store.Git.create ~backend → Store.Git.create ~backend () (new unit arg)
- Add type annotations on run_all_* conf parameters for record disambiguation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each scenario (commits, reads, incremental) now runs twice: once with
small values (configurable via --value-size, e.g. 20B for inlining tests)
and once with 10K values. Scenario names include the size suffix
(e.g. commits-20B, reads-10K).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LRU cache is the main win on disk (5.2× reads). Inodes and inlining
have no benefit — disk I/O is the bottleneck.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --skip-memory CLI option
- Add ?inode and ?name parameters to run_all_disk
- Update run_optims.sh to run both disk and memory variants
- Generate separate chart_optims_disk and chart_optims_memory SVGs
- Show disk optimizations before memory in README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace orange (#f28e2b) and red (#e15759) with brown (#9c755f) and
purple (#b07aa1) so optim variants don't share colors with Irmin-Lwt
and Irmin-Eio in other charts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow regenerating per-optimization benchmarks via run_optims.sh,
which runs 5 variants (baseline, +inline, +cache, +inode, +all) on
the memory backend and merges results into irmini_optims.json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recover benchmark data from previous commits (baseline, +inline, +cache,
+inode, +all) into irmini_optims.json. Add "optims" chart category to
gen_chart_all.py. Update README with optimization breakdown showing
inodes as the biggest single optimization (220x commits, 21x reads).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Regenerate all 3 charts (disk, memory, git) with irmini-git data.
Reorder README: disk first, then memory, then git. Add irmini-git
analysis — 3.6x faster than Irmin on git commits, 100% compatible.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add run_all_git with inode:false for full git compatibility
- Expose git_backend in git_interop.mli
- Add --skip-git option to bench runner
- Rewrite gen_chart_all.py: 3 charts (disk, memory, git), ordered
by family (irmin-lwt, irmin-eio, irmini), explicit color map,
dynamic legend layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tree.hash and Store.commit now accept ?inode:bool (default true).
When inode:false, large tree nodes are always written as flat nodes
instead of being split into inode tries. Existing inode nodes are
expanded back to flat format. This ensures 100% git-compatible output
without limiting tree size.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix bench-lwt adapters to use Irmin.Generic_key.KV (for irmin-pack
compatibility) and fully Lwt-native scenarios (no nested Lwt_main.run).
Add irmin-lwt benchmark results for memory, pack, fs, and git backends.
Update README with three-chart organization (memory, disk, git) and
comparative analysis across Irmin-Lwt, Irmin-Eio, and Irmini.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add bench-lwt/ adapters for irmin-lwt (main branch) with memory, fs,
git, and pack backends. Update bench-eio/ to include irmin-fs and
irmin-git backends alongside memory and pack. Add JSON output (--json)
to all benchmark runners for machine-readable results.
New orchestration script (bench/run_all.sh) coordinates benchmarks
across all implementations: irmin-lwt, irmin-eio, irmini-thomas, and
irmini with their respective backends.
New chart generator (bench/gen_chart_all.py) produces separate SVG
charts grouped by backend type: memory, disk (fs/pack/lavyek), and git.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add individual optimization benchmarks for lavyek backend (baseline,
+inline, +cache, +inode, +all) in run_bench.sh, gen_chart_all.py,
and gen_readme_results.py
- Clean irmini_trace.json: remove spurious standard benchmark entries
(100B values with +cache names) that polluted the memory optims chart
- Remove --cache from trace replay section (now default in backends)
- Use consistent colors and order across all optimization charts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Key improvements vs previous run:
- Irmini (memory) commits-20B: 71k -> 231k ops/s (3.2x)
- Irmini (memory) tezos replay: 71k -> 142k ops/s (2x, now beats irmin-lwt)
- Irmini (lavyek) commits-20B: 84k -> 204k ops/s (2.4x)
- Irmini (disk) commits-20B: 2k -> 32k ops/s (16x)
- All reads now >1M ops/s across backends
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scenarios now always appear in the same order on charts as in the
README documentation: commits-20B, reads-20B, incremental-20B,
commits-10K, reads-10K, incremental-10K, concurrent, tezos.
Previously the order depended on the order of appearance in the
JSON result files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inlined contents (≤48 bytes) are stored directly in the parent node
and must always be included in proofs to preserve the node hash
during verification. The blinded nodes test now uses values larger
than the inline threshold (64 bytes) so they are stored as separate
blobs and can be properly blinded.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Buffer all writes during Tree.hash into a local list with a
read-through cache, then flush everything as a single write_batch
at the end of commit. This is especially beneficial for the disk
backend where each individual write triggers a WAL sync (fsync).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a node has no pending modifications (empty children map and
empty removed set) and already has a known hash (Inode or Lazy state),
return the existing hash directly without recursing, serializing,
or writing to the backend. This avoids redundant work during commit
for the large majority of tree nodes that are unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace O(n) association lists with O(log n) Map.Make(String) for
children modifications and Set.Make(String) for removed entries.
This eliminates linear scans in navigate, add_at, remove, and
write_tree which were a bottleneck on large tree nodes (e.g. the
Tezos genesis commit with ~309k operations).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename chart SVGs from timestamped names to stable names (chart_disk.svg, etc.)
- Update README references accordingly
- run_bench.sh: remove crashing Irmin-Eio fiber sweep (only 1 fiber is stable),
add auto-generation of tezos_parallel.json from parallel results
- gen_readme_results.py: classify parallel tezos entries (12d×) as disk,
add parallel trace-replay bullet in disk analysis
- gen_chart_all.py: dynamic parallel variant detection via is_parallel_variant(),
dynamic color resolution for new parallel variant names
- Regenerate README from JSON results for consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Irmin-Eio (pack) achieves 1.9x speedup with 12 domains × 1 fiber on the
full 10310-commit Tezos trace (205k vs 107k ops/s). Limited by irmin-pack's
serialized batch mechanism. Irmin_mem is not domain-safe (removed from
parallel benchmarks). Documents the architectural contrast with irmini's
lock-free Lavyek backend (94x on same trace).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Irmin-Eio (PR #2149) supports multicore via Kcas hashtables, atomics,
and Eio.Mutex. Add trace_replay_irmin.ml with a Make(S) functor that
replays Tezos traces on any irmin KV store, both sequentially and in
parallel across domains × fibers.
Tested: 4d×2f gives 7x speedup on memory, 18x on pack (tree ops
run in parallel; only commits are serialized by batch mechanism).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single entry point to run all benchmarks and update README:
- 7 steps: irmini standard, optimizations, trace replay, parallel
scaling (14 fiber counts), irmin comparison + trace, charts, README
- gen_readme_results.py generates Results section from JSON files
- gen_chart_parallel.py now reads data from JSON (--json flag)
- Irmin trace replay automated when IRMIN_DIR is set
- Full run_bench.sh options documented in README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Irmin-Lwt and Irmin-Eio pack-mem trace replay results to JSON files
so they appear in the memory backends chart alongside Irmini (memory).
Irmini (lavyek) tezos results appear in the disk chart. Removed the
separate tezos chart category since all backends are memory-based.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Run irmin's official tree.exe trace replay (pack-mem, no GC) on both
branches for comparison with irmini results:
- Irmin-Lwt (main): ~131K ops/s in 30.6s CPU
- Irmin-Eio (cuihtlauac): ~83K ops/s in 48.1s CPU
- Irmini (memory): 71K ops/s in 56.3s
- Irmini (lavyek): 68K ops/s in 58.8s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Modify bench_irmin4_main to run trace replay on each active backend
(memory, disk, lavyek) instead of hardcoded memory
- Add trace replay results: memory 71K ops/s, lavyek 68K ops/s
- Fix mislabeled "Irmini (disk) trace-replay" → was actually memory
- Disk backend too slow for trace replay (WAL fsync per write)
- Update README and regenerate charts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ocaml-wal off-by-one bug (block_remaining < header_size → <=) has
been fixed, allowing the disk backend to complete all scenarios.
New results:
- irmini_disk.json: 7 scenarios (commits, reads, incremental, concurrent)
- irmini_optims_disk.json: rerun with WAL+bloom backend (5 variants × 7 scenarios)
WAL fsync dominates write-heavy scenarios; inodes help commits (3x),
cache helps reads (10x for large objects).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite Results section with data from rerun benchmarks:
- Order: disk, memory, git, optims disk, optims memory, tezos replay
- All scenarios use 20B small values (below inlining threshold)
- trace-replay shown as scenario in disk chart
- Updated analysis to reflect new numbers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add fmt_size to both Irmin adapter bench_common.ml
- Use size-suffixed scenario names (commits-20B, reads-10K, etc.)
- Run each scenario twice (small + large values) like irmini
- Remove separate large-values scenario (now covered by dual-run)
This ensures all three implementations produce identically-named
scenarios so chart bars are grouped correctly for comparison.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fresh benchmark run on 2026-03-10 comparing:
- Irmin-Lwt (main branch): memory, pack, fs, git
- Irmin-Eio (cuihtlauac branch): memory, pack, fs, git
- Irmini (inode branch): memory, git
Key findings: irmini 4.5x faster on git commits (7.9k vs 1.8k ops/s)
with 13x less memory, 2.9x faster on incremental updates.
Tezos trace replay: 73K ops/sec over 10K commits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reads .repr trace files (IrmRepBT format) and replays recorded Tezos
operations (Checkout, Add, Remove, Copy, Find, Mem, Commit) on an
Irmini store. Uses the repr library for binary decoding.
New CLI options: --trace, --trace-commits, --trace-empty-blobs, --no-flatten
Tested on data4_10310commits.repr: 10310 commits, 4M ops in 55s (73K ops/sec).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bloom.v → Bloom.create (API change in ocaml-bloom)
- PathSet → Path_set (typo in proof.ml)
- Atp.Mst.find → Atp.Mst.get (API rename in ocaml-atp)
- Store.Git.create ~backend → Store.Git.create ~backend () (new unit arg)
- Add type annotations on run_all_* conf parameters for record disambiguation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --skip-memory CLI option
- Add ?inode and ?name parameters to run_all_disk
- Update run_optims.sh to run both disk and memory variants
- Generate separate chart_optims_disk and chart_optims_memory SVGs
- Show disk optimizations before memory in README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recover benchmark data from previous commits (baseline, +inline, +cache,
+inode, +all) into irmini_optims.json. Add "optims" chart category to
gen_chart_all.py. Update README with optimization breakdown showing
inodes as the biggest single optimization (220x commits, 21x reads).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add run_all_git with inode:false for full git compatibility
- Expose git_backend in git_interop.mli
- Add --skip-git option to bench runner
- Rewrite gen_chart_all.py: 3 charts (disk, memory, git), ordered
by family (irmin-lwt, irmin-eio, irmini), explicit color map,
dynamic legend layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tree.hash and Store.commit now accept ?inode:bool (default true).
When inode:false, large tree nodes are always written as flat nodes
instead of being split into inode tries. Existing inode nodes are
expanded back to flat format. This ensures 100% git-compatible output
without limiting tree size.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix bench-lwt adapters to use Irmin.Generic_key.KV (for irmin-pack
compatibility) and fully Lwt-native scenarios (no nested Lwt_main.run).
Add irmin-lwt benchmark results for memory, pack, fs, and git backends.
Update README with three-chart organization (memory, disk, git) and
comparative analysis across Irmin-Lwt, Irmin-Eio, and Irmini.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add bench-lwt/ adapters for irmin-lwt (main branch) with memory, fs,
git, and pack backends. Update bench-eio/ to include irmin-fs and
irmin-git backends alongside memory and pack. Add JSON output (--json)
to all benchmark runners for machine-readable results.
New orchestration script (bench/run_all.sh) coordinates benchmarks
across all implementations: irmin-lwt, irmin-eio, irmini-thomas, and
irmini with their respective backends.
New chart generator (bench/gen_chart_all.py) produces separate SVG
charts grouped by backend type: memory, disk (fs/pack/lavyek), and git.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>