You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf: Reduce CPU overhead in turbo run hot path (#11947)
## Summary
Several targeted optimizations to reduce CPU time in `turbo run`'s
critical path. These changes reduce allocations, eliminate redundant
computation, and improve algorithmic complexity in per-package
operations.
### Per-function improvements (absolute self-time)
| Function | Repo | Before | After | Change |
|---|---|---|---|---|
| `calculate_task_hash` | large | 101ms | <1ms | **eliminated from top**
(cached) |
| `walk_glob` | large | 218ms | 111ms | **-49%** |
| `calculate_task_hash` | medium | 26ms | 17ms | **-35%** |
| `walk_glob` | medium | 41ms | 29ms | **-30%** |
| `to_summary` | small | 7ms | 6ms | -25% |
## Changes
- **Binary-search status lookups in `RepoGitIndex`**: Status entries are
now sorted at index build time. Per-package filtering uses
`partition_point` for O(log N) range queries instead of O(N) linear
scans. Matters when both package count and dirty-file count are large.
- **Precompute external dependency hashes per-package**:
`get_external_deps_hash` sorts transitive dependencies and hashes them.
Previously this ran for every task. Now it runs once per package and is
cached, since multiple tasks in the same package produce the same hash.
`TaskHashable.external_deps_hash` changed from `Option<String>` to
`Option<&str>` to avoid cloning from the cache.
- **Combined branch+SHA libgit2 lookup**: `to_summary` previously opened
the git repo twice (once for branch, once for SHA). Now a single
`Repository::open` call retrieves both.
- **Reuse buffers in ls-tree and hash-object walks**: The tree walk and
hash-object loops now reuse a `String` path buffer and a `[u8; 40]` hex
buffer instead of allocating per entry. Uses `hex::encode_to_slice`
instead of `git2::Oid::to_string`.
### Wall-clock caveat
These CPU improvements don't translate cleanly to wall-clock time in
benchmarks because `git status` and `git ls-tree` via libgit2 dominate
total runtime (30-80% of profiled duration) and have high I/O variance
between runs. The functions we optimized are real work that runs on
every `turbo run`, but measuring end-to-end improvement requires many
runs to overcome the git I/O noise floor.
## Testing
All existing tests pass. Added regression tests for:
- Sorted status binary-search correctness (prefix boundary, delete
handling, empty prefix)
- External deps hash determinism, order-independence, and empty-set
behavior
- TaskHashTracker pre-sized HashMap behavior
0 commit comments