What was optimized
The experiment rebuilt four command-line tools for the exact Apple CPU in the machine:
- Vim with
-O3 -mcpu=native -ffp-contract=fast -flto; - ripgrep with Rust's upstream
release-ltoprofile andtarget-cpu=native; - Universal Ctags with
-O3 -mcpu=native, LTO, and optional PGO; - Git's main executable and builtins with
-O3 -mcpu=native -fltoand optional PGO.
These are not generic replacements for Homebrew bottles. A bottle is built once for a compatible Apple Silicon baseline and distributed to many Macs. A native build can use the scheduling model and instruction set of one detected generation, such as apple-m1 or apple-m4, but it gives up that portability.
The measurements also come from two machines. The recorded Vim CPU benchmark used an Apple M4. The ripgrep, Ctags, and Git measurements used an M1 Pro. Results should be read within each same-machine, same-version comparison, not as a ranking between those Macs.
Vim: remove startup work first
Vim is the best place to start because two independent kinds of work were measured. Plugin sourcing affects every launch; native compilation affects CPU-bound work after Vim is running.
Repeated --startuptime logs showed that removing unnecessary plugins and lazy-loading command-driven features mattered more than compiler flags:
The total fell from 36.079 ms to 3.325 ms, about 90.8% less plugin startup work. That is a 10.85x ratio between the first and final plugin totals, not a claim that the complete editor launches 10.85x faster. Vim itself, dynamic libraries, the terminal, filesystem caches, and the rest of .vimrc remain part of total startup.
The lazy-loading boundary is the command that first needs a plugin:
nnoremap <C-n> :packadd nerdtree <Bar> NERDTreeToggle<CR>
augroup tabular_lazy
autocmd!
autocmd CmdUndefined Tabularize packadd tabular
augroup END
augroup fugitive_lazy
autocmd!
autocmd CmdUndefined Git,G,Gstatus,Gblame,Glog,Gclog,Gwrite,Gread,Gdiffsplit,Gvdiffsplit,GBrowse packadd fugitive | packadd vim-rhubarb
augroup END
Only after reducing startup work did the executable build become worth testing. On the M4, the native binary improved CPU-heavy regex and Vimscript workloads while a memory-bound sort moved much less:
The defensible result is narrow: 15-23% speedups in these CPU-bound operations, and about 4% for the memory-bound sort. Native compilation complements startup cleanup; it cannot compensate for loading plugins that should not run.
ripgrep: PGO helped one trained workload
ripgrep already ships as an efficient Rust program with a strong release profile. Its native/LTO build was effectively neutral against the Homebrew ARM64 Tahoe bottle on the M1 Pro. Most differences were around 1%, below the useful resolution of these short runs. Unicode regex improved by 2%.
The optional PGO workflow builds an instrumented executable, trains literal, regex, Unicode, PCRE2, traversal, and 1/2/4/8/default-thread workloads, merges the LLVM profiles, then performs a clean final LTO build.
PGO materially improved the trained Unicode-regex workload. Most other changes were small, and traversal regressed. Thread count had a larger effect on literal search than PGO: automatic threading was 2.32x faster than the PGO build's one-thread median on this corpus.
The result is not “custom ripgrep is faster.” It is that PGO can help a representative hot path, while the standard bottle remains a very strong general default.
Git: same contract, no measured win
Git was the most demanding compatibility case and the least exciting benchmark result. The build script derives the active Homebrew version and checksum-verified source from the installed formula snapshot, then fails closed if the formula's feature or runtime-path contract has changed. Homebrew's main git executable also implements its builtins through symlinks such as git-add and git-status, so replacing that one file optimizes builtins without claiming that external helpers were rebuilt.
The candidate must preserve Git's CommonCrypto choice, PCRE2 and gettext linkage, system libcurl and libiconv, SHA implementations, shell path, executable path, documentation paths, and FALLBACK_RUNTIME_PREFIX. Smoke tests create temporary repositories and exercise commits, branches, PCRE2 grep, fsck, garbage collection, bundles, and clones without reading global Git configuration.
The native and PGO builds were neutral at the benchmark's 0.01-second reporting resolution. That is still useful evidence: a safe, reproducible build workflow does not imply that installing its output is worthwhile for every tool.
What LTO and PGO contribute
Link-Time Optimization (LTO) keeps compiler information through the link stage so optimization can cross source-file and library boundaries. It can inline across translation units and remove code that is unused once the complete executable is visible. LTO costs build time and memory but adds no profiling instrumentation to the final binary.
Profile-Guided Optimization (PGO) is a two-stage process. An instrumented build records which functions and branches the training workload uses. A second build consumes the merged profile to improve hot-path layout, inlining, and branch decisions. The final executable has no training overhead.
PGO's weakness is also its purpose: it specializes for observed behavior. Ctags' parser workloads and ripgrep's Unicode regex benefited. ripgrep traversal regressed, Ctags' mixed corpus was neutral, and Git did not move. Training must resemble real use, and the final decision still belongs to an independent benchmark.
Rebuild and restore commands
Each script supports a bottle restoration path because the Homebrew receipt continues to describe the formula installation after a binary-only replacement.
# Vim
./bootstrap/native/compile_vim_native.sh
brew unpin vim && brew reinstall vim
# ripgrep
./bootstrap/native/compile_ripgrep_native.sh --pgo
brew unpin ripgrep && brew reinstall ripgrep
# Universal Ctags
brew install docutils llvm
./bootstrap/native/compile_ctags_native.sh --pgo
brew unpin universal-ctags && brew reinstall universal-ctags
# Git
brew install llvm pkgconf
./bootstrap/native/compile_git_native.sh --pgo
brew unpin git && brew reinstall git
After a formula upgrade, unpin and upgrade first, inspect the changed formula contract, then rerun the corresponding script. The Git workflow follows the active version automatically but intentionally stops when the formula's build contract changes.
Where the evidence lands
The experiment produced four different answers:
- Vim: removing plugin startup work was the largest everyday improvement; native compilation helped CPU-bound microbenchmarks.
- ripgrep: native/LTO was neutral; PGO materially helped Unicode regex but not traversal.
- Universal Ctags: native/LTO and PGO both improved trained language parsers.
- Git: native/LTO and PGO preserved behavior but did not measurably improve the aggregate workload.
The general lesson is not to rebuild every Homebrew formula. It is to make optimization falsifiable: preserve the package contract, compare the same version, train PGO on representative work, publish regressions beside gains, and keep a one-command route back to the bottle.
The implementation lives in bootstrap/, benchmarks/, and the concise command summary in the dot-files README.