perf(unix): reduce allocation in post-I/O yields - #605
Merged
Merged
Conversation
Guest0x0
approved these changes
Sep 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Successful Unix reads and writes yield through
protect_from_cancel(() => pause())before returning their result. This adds an internalpause_after_iohelper that performs the same protected yield without the generic higher-order cancellation wrapper, reducing allocation on this path.The helper preserves every existing yield, queues the coroutine in the same order, and saves/restores its previous cancellation shield. Pending cancellation is delivered at the next cancellation point after returning the completed I/O result. The paths that wait for I/O readiness are unchanged. Four regression tests cover round-robin scheduling, cancellation pending before the yield, cancellation during suspension, and an enclosing cancellation shield.
I collected these measurements while benchmarking Mars, my web server implementation. The detailed results, methodology, limitations, reproduction commands, and raw data are in Mars. This standalone comparison uses async main at
43e41261f99261f4030efbed1970388930229baa; it does not include #603 or #604.These are native release measurements on macOS arm64. Separate binaries measure allocation and elapsed time; the yield-only microbenchmark's elapsed time is nearly unchanged. The real-server comparison uses six paired rounds with alternating order, a one-second warmup and five-second load, four wrk threads, and 64 connections. All six rounds reduce instructions/request by 1.65–2.20%. The allocation reduction is the primary motivation; these runs do not establish Linux performance or production throughput.
Local validation:
moon check --deny-warnpasses for native, JS, Wasm, and Wasm-GC;moon fmtandmoon infoare clean.Linux native execution is covered by the upstream PR CI. This PR is based directly on main and is independent of #603 and #604.