Skip to content

Commit 3f45941

Browse files
authored
perf(install): improve parallelism of fetches during npm resolution (#32416)
disclosure: profiling and optimization idea by me, code changes (and the rest of this PR description) by claude Before resolve_pending processes one parent node at a time sequentially. Inside resolve_next_pending, it uses FuturesOrdered to fetch package info for that single parent's dependencies concurrently — but there is no overlap between parents. If parent A has deps [x, y, z] and parent B has deps [p, q], we fetch x/y/z concurrently, wait for them all to be processed, then move to B and fetch p/q. Newly discovered children go to the back of the queue and can't start fetching until every previously-queued parent finishes. After drain_pending_parallel drains all pending parent nodes into a single FuturesUnordered, so all parents' dep fetches are in-flight simultaneously. Results are buffered per-parent and retired in FIFO order (by insertion order) to preserve deterministic resolution — even though network responses arrive out of order, we process parents in the same order the old code would have. When a parent is retired and its deps are processed, any newly discovered child nodes are immediately enqueued into the same FuturesUnordered. This means we don't wait for the entire current BFS level to complete before starting the next — child fetches overlap with sibling parent fetches, giving cross-BFS-level parallelism. Results --- ``` Benchmark 1: /Users/nathanwhit/Documents/Code/deno/target/deno-baseline install Time (mean ± σ): 8.295 s ± 0.879 s [User: 1.196 s, System: 3.599 s] Range (min … max): 7.028 s … 9.758 s 10 runs Benchmark 2: /Users/nathanwhit/Documents/Code/deno/target/release-lite/deno install Time (mean ± σ): 3.342 s ± 0.344 s [User: 0.981 s, System: 3.297 s] Range (min … max): 2.992 s … 4.138 s 10 runs ```
1 parent 74cc882 commit 3f45941

1 file changed

Lines changed: 355 additions & 139 deletions

File tree

0 commit comments

Comments
 (0)