Repository navigation
perf(check): a call's pending arguments are a cons list, and parameters flatten in one loop - #1967
Merged
nicolas-abril merged 2 commits intoNov 2, 2026
Conversation
…rs flatten in one loop (part of #1956)
Contributor
|
Verified against current main ( In 7 interleaved runs on a 2,048-argument call, this was consistently faster (~0.33–0.38s vs ~0.38–0.46s on main, startup included). Two asks:
|
5 of 7 tasks
Contributor
Author
|
Thanks for checking it. Both asks:
|
nicolas-abril
added a commit
that referenced
this pull request
Nov 2, 2026
Level order changed which @unsafe binder type a program hangs on, and the batched var columns saved about 0.02 s while dropping the error that guarded them. #1965 fixes #1955 and #1967 fixes the call spine and body_flatten, so this is now the fields #1956 still names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Part of #1956: the call spine and
body_flatten. Constructor fields are left for later (see the end).Checking a call
f(a1, …, an)walks its nestedApps towardf, and each step built the pending arguments as a new array,[tm.x, ...sp], so a call with n arguments copied n(n-1)/2 entries. Flattening a def's n parameters did the same withbody_flatten(b, vars.slice(1), fr).Change (
bend2/bend.tsonly)term_infer: the spine is aList<HTerm>, the file's existing cons list, andApppasseslist_set(sp, 0, tm.x)(a cons; the key is unused). TheRefcase reads it into an array once, only whenqtis not None, anddef_inst, theslice(x)and the decreasing-call loop use that array as they usedsp. No other caller passes a spine.body_flatten, default arm: a loop from the last parameter to the first wraps the sameLams. The recursion always landed in this arm again, sincebdoes not change.No cache and no memo: it only drops copies (#993, #1075).
Measured on the issue's
discardwith n parameters and a call with n arguments,--check-only:body_flattenentries copied, beforeBefore is n(n-1)/2 in both places; after, the spine is read once (n entries) and
body_flattencopies nothing. For n = 2 the spine read costs one entry more than before. Copies were counted with temporary counters, since removed; times are medians of 7 runs, before and after alternated.Checker benches, medians of 5 alternated runs: compute_1600 501 → 503 ms, defs_12800 285 → 289, generics_3200 380 → 374, proofs_3200 817 → 777 (ranges 814–840 and 763–824 overlap; Linux below shows no change), trees_400 810 → 809. So this only matters for calls with many arguments.
On Linux, medians of 7: n = 512 27 → 23 ms, 2048 59 → 42 ms, 8192 381 → 104 ms; checker benches compute_1600 609 → 601, defs_12800 378 → 380, generics_3200 457 → 445, proofs_3200 931 → 926, trees_400 1159 → 1145.
Verification (macOS arm64, Bun 1.4.2; Linux arm64 (Docker, Debian 13, Bun 1.4.2, clang 19))
body_flatten, n = 2 to 8192, macOS: the table abovetests/, interpreter, before vs after, macOS and Linux: no difference (on macOSproof/app/main, which greets until killed, is not comparable; on Linux its output is capped at 1 MB and matches)gates/repo.ts: 54/54 (bend.ts 44,532 / 48,000 ttok)tscof bend.ts alone: the same 19 errors before and after, all missing typesgates/test.ts,gates/perf.ts: run on the minisLeft out: the constructor-field copies the issue also names (
[...xs, x]inlhs_ext,xs.concat([x])interm_check_mat_goal) sit inside term bodies built as functions that can run more than once, so they need a different change. Hence "part of".Note: #1734 reads
sp[j]andsp.lengthin theRefcase; there the array is nowxs, so whichever lands second needs a small rebase.