Benchmarks: S1's first round on the Linux tree (refs #41) bd9414401fdc
- Author
- Andy McCall @andymccall <[email protected]>
- When
- · 2026-09-30 21:55 UTC
- Signature
- ✔ signed by Andy McCall
- Hash
bd9414401fdcf3c5bb8073bf523139d1d6270ac1389519fc8ac7485882ad005c- Depends on
- 1d360c91a289 61e9ad6ddc2d e4b8bcf04a86
- Depended on by
- e82591ec33a4
- 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
| … | 115 unchanged lines |
||
| 116 | 116 | changed-only builds and the manifest cache already in). |
|
| 117 | 117 | ||
| 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 | + | ||
| 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. |
modified docs/benchmarks.md +41 −0
| … | 626 unchanged lines |
||
| 627 | 627 | (48 s against 100 s). The store after gc grew from 324 MB because it now |
|
| 628 | 628 | includes the workspace's state index. |
|
| 629 | 629 | ||
| 630 | + | ||
| 631 | + | ### S1, first part: walk, manifest, lazy index, mimalloc (2026-09-30 22:39, oxygen#41) |
|
| 632 | + | ||
| 633 | + | The same script after the first round of S1: a lister of our own in place |
|
| 634 | + | of the ignore crate's walker, the manifest as a flat binary file with |
|
| 635 | + | hashes as bytes, each file's history in the state index decoded only when |
|
| 636 | + | used, maps built in path order, and mimalloc as the allocator. Earth's |
|
| 637 | + | load average was 4 to 5 (no Flow jobs); runs alternate with Git. |
|
| 638 | + | ||
| 639 | + | | Operation | oxy | before (21:43) | Git | |
|
| 640 | + | |---|---:|---:|---:| |
|
| 641 | + | | init and commit the tip | **24.4 s**, 3.2 GB | 33.3 s, 3.1 GB | 36.2 s | |
|
| 642 | + | | status, clean | **0.17 to 0.18 s**, 130 to 150 MB | 0.43 to 0.53 s | 0.22 to 0.23 s | |
|
| 643 | + | | status, one file | 0.47 s (1.47 s first) | 1.73 to 1.81 s | 0.22 to 0.23 s | |
|
| 644 | + | | diff, one file | 0.47 to 0.51 s | 1.77 to 2.24 s | 0.11 to 0.14 s | |
|
| 645 | + | | commit, one file | 0.96 s | 3.10 s | 0.17 s | |
|
| 646 | + | | status, 1 000 files | 0.65 s (1.99 s first) | 1.62 s | 0.23 to 0.24 s | |
|
| 647 | + | | diff, 1 000 files | 0.65 s | 1.54 to 2.40 s | 0.46 to 0.48 s | |
|
| 648 | + | | commit, 1 000 files | 1.20 s | 2.47 s | 0.50 s | |
|
| 649 | + | | log -n 100 | 0.48 to 0.53 s | 0.86 to 1.03 s | 0.00 s | |
|
| 650 | + | | blame MAINTAINERS | 0.59 s | 0.99 to 1.04 s | 0.07 s | |
|
| 651 | + | | clone, local path | 36.7 s, 3.6 GB | 56.3 s | 18.0 s | |
|
| 652 | + | | checkout the first state, and back | 1.48 s, 1.37 s | 2.86 s, 3.00 s | 0.35 s, 0.34 s | |
|
| 653 | + | | fsck | 14.0 s, 1.0 GB | 24.4 s | 12.6 s | |
|
| 654 | + | | gc | **29.9 s** | 48.1 s | 70.3 s | |
|
| 655 | + | | store after gc | 369 MB | 375 MB | 295 MB | |
|
| 656 | + | ||
| 657 | + | mimalloc alone took one-file status from 0.78 to 0.47 s and clean status |
|
| 658 | + | from 0.26 to 0.18 s: status allocates hundreds of thousands of small |
|
| 659 | + | values from every thread, and glibc's arena locks were the largest single |
|
| 660 | + | cost. The first status after a commit (1.47 s) rebuilds the state index. |
|
| 661 | + | ||
| 662 | + | Afterwards (22:55), log reads change metadata from the state index and a |
|
| 663 | + | metadata cache in the store, and its signature marks no longer read each |
|
| 664 | + | change whole: `log -n 100` takes 0.19 to 0.20 s, of which 9 ms is the log |
|
| 665 | + | itself and the rest the check that the working copy is clean. |
|
| 666 | + | ||
| 667 | + | Where one-file status goes now (0.47 s): listing the working copy about |
|
| 668 | + | 150 ms (the syscalls alone: `find` with a stat of each file takes 0.37 s |
|
| 669 | + | on one core), loading the state index about 60 ms, reading the manifest |
|
| 670 | + | about 40 ms, rendering and diffing the changed file about 100 ms. |