Benchmarks: the second round on the Linux tree (refs #41) e82591ec33a4
- Author
- Andy McCall @andymccall <[email protected]>
- When
- · 2026-09-30 23:00 UTC
- Signature
- ✔ signed by Andy McCall
- Hash
e82591ec33a43573338641ae9113f0fecbf2d3b5f584360e797cdf1805ce29e1- Depends on
- 1d360c91a289 61e9ad6ddc2d bd9414401fdc
- Depended on by
- cd19603782bf 72215f29df4c
- In bookmarks
- agents-in-readme bare-hashes carried-not-removed carry-identical doctor-trust identical-sides keyless-tags main merge-remote-bookmark only-help-103 paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state switch-says
- In tags
- v0.10.0 v0.11.0 v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.4.6 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
- Edits
- 2 atoms, 0 tree operations, 2 files
Browse the tree at this change
modified docs/backlog-overnight-4.md +2 −0
| … | 117 unchanged lines |
||
| 118 | 118 | - 2026-09-30 **B0** baseline (table in `docs/benchmarks.md`; `linux-bench.sh` now runs three of each, alternating, plus a local clone; the loop-3 script is kept as `linux-bench.sh.loop3`). oxy is ahead on the first commit (33.3 s against 38.2 s) and gc (48 s against 100 s); clean status is close (0.43 to 0.53 s against 0.34 to 0.46 s). Behind: dirty status and diff (1.5 to 2.2 s against 0.3 to 0.8 s), commit (2.5 to 3.1 s against 0.4 to 0.5 s), log (0.9 s against 0.00 s), blame (1.0 s against 0.07 s), checkout (3 s against 0.4 to 0.5 s), fsck (24 s against 13 s), and a new gap: a local clone takes 56 s and 3.3 GB against Git's 18 s. The store after gc is 375 MB (it now includes the 48 MB state index) against 295 MB. |
|
| 119 | 119 | ||
| 120 | 120 | - 2026-09-30 **S1, first round** (commits c9dca9ed to 077e899b; table in `docs/benchmarks.md`). A lister of our own replaces the ignore crate's walker (listing 0.5 s to 0.18 s); the manifest is a flat binary file with hashes and graph keys as bytes; the state index keeps each file's history encoded until used (a writer bug I made on the way was caught only on Earth, since a failed index read falls back to a full load: test builds now read every index written back); maps are built in path order; mimalloc is the allocator. Clean status is now ahead of Git (0.18 s against 0.22 s), the first commit too (24.4 s against 36.2 s), and gc (29.9 s against 70.3 s). One-file status is 0.47 s against 0.22 s. Log (S3, first part): metadata from the state index and a store cache, signature marks without reading changes: 0.20 s, of which 9 ms is the log. For Andy: `oxy log` checks the working copy first (about 0.18 s here); Git's log does not look at it. Dropping that check would make log about 20 ms, but the working-copy line would then show the last snapshot's state. |
|
| 121 | + | ||
| 122 | + | - 2026-10-01 00:00 **Second round** (6359f779 to 81a5bdd7; table in `docs/benchmarks.md`). Commit 0.67 s (from 0.96 s): the state index is brought up to date by replaying and rewritten only 16 changes behind; keys only for changed paths; attributes from the snapshot rather than a tree walk; the manifest checksummed and written without fsync; and a fix: after a status had seen an earlier edit, a commit kept that edit's stat in the manifest, so every later status took a full snapshot. Blame 0.16 s (from 0.59 s; Git 0.07 s), log 0.18 s, checkout 0.74 s each way (from 1.4 s) with two state indexes kept per workspace, and status right after a checkout that wrote 1 000 files 0.18 s (from 1.3 s). **R1** done: `oxy rebase --into-working-copy` (closes #42). |
modified docs/benchmarks.md +32 −0
| … | 667 unchanged lines |
||
| 668 | 668 | 150 ms (the syscalls alone: `find` with a stat of each file takes 0.37 s |
|
| 669 | 669 | on one core), loading the state index about 60 ms, reading the manifest |
|
| 670 | 670 | about 40 ms, rendering and diffing the changed file about 100 ms. |
|
| 671 | + | ||
| 672 | + | ### S1 to S5, second round (2026-09-30 23:54, oxygen#41) |
|
| 673 | + | ||
| 674 | + | After the second round: merge joins over whole-tree maps, a commit that |
|
| 675 | + | works out keys only for what it changed and brings the state index up to |
|
| 676 | + | date by replaying rather than rewriting it, the manifest checksummed and |
|
| 677 | + | written without fsync, log and blame from the state index, checkout |
|
| 678 | + | through the index with two indexes kept. Load average 4.2 at the start, |
|
| 679 | + | no Flow jobs. |
|
| 680 | + | ||
| 681 | + | | Operation | oxy | 22:39 | Git | |
|
| 682 | + | |---|---:|---:|---:| |
|
| 683 | + | | init and commit the tip | **21.9 s**, 3.2 GB | 24.4 s | 33.7 s | |
|
| 684 | + | | status, clean | **0.17 to 0.19 s** | 0.17 to 0.18 s | 0.22 s | |
|
| 685 | + | | status, one file | 0.40 to 0.41 s (1.10 s first) | 0.47 s | 0.22 to 0.24 s | |
|
| 686 | + | | diff, one file | 0.39 to 0.48 s | 0.47 to 0.51 s | 0.10 to 0.11 s | |
|
| 687 | + | | commit, one file | 0.67 s | 0.96 s | 0.21 s | |
|
| 688 | + | | status, 1 000 files | 0.58 to 0.65 s | 0.65 s | 0.23 to 0.24 s | |
|
| 689 | + | | diff, 1 000 files | 0.59 to 0.62 s | 0.65 s | 0.46 to 0.48 s | |
|
| 690 | + | | commit, 1 000 files | 0.88 s | 1.20 s | 0.48 s | |
|
| 691 | + | | log -n 100 | 0.17 to 0.19 s | 0.48 to 0.53 s | 0.00 s | |
|
| 692 | + | | blame MAINTAINERS | 0.16 s | 0.59 s | 0.07 to 0.16 s | |
|
| 693 | + | | clone, local path | 32.2 s, 3.6 GB | 36.7 s | 17.0 s | |
|
| 694 | + | | checkout the first state, and back | 0.74 s, 0.74 s | 1.48 s, 1.37 s | 0.37 s, 0.33 s | |
|
| 695 | + | | fsck | 13.6 s | 14.0 s | 12.6 s | |
|
| 696 | + | | gc | **29.4 s** | 29.9 s | 70.2 s | |
|
| 697 | + | | store after gc | 369 MB | 369 MB | 295 MB | |
|
| 698 | + | ||
| 699 | + | The first one-file status after the first commit (1.10 s) builds the |
|
| 700 | + | state index for the first time. Most of what remains in status is listing |
|
| 701 | + | the tree (about 135 ms), loading the index (about 60 ms) and starting up; |
|
| 702 | + | commit adds storing and recording with fsync (about 100 ms). |