Commit ff70d6c
fix(quickcheck): produce shrink candidates without recursing per block
Replace the recursion in `removes_array` and `removes_list` with a cursor over
the block offsets. Both now walk `0, k, 2k, ..` directly — ascending for the
array, descending for the list — so building the iterator is O(1) and yielding
a candidate uses no stack beyond the call itself. The candidate sequences and
`size_hint`s are the ones the previous commit pinned, which is why that test
file is unchanged here.
This fixes the three stack-overflow tests from the previous commit on js, wasm
and wasm-gc, so a property test whose counterexample is a large collection now
shrinks instead of dying with `RangeError: Maximum call stack size exceeded`.
It is also much faster on the `List` side, because the old form rebuilt the
candidate through one `concat` per level on the way back up, where the new one
does a single `take`/`drop`/`concat`. First candidate from a 10,000-element
collection, native release:
| Collection | Before | After |
| ---------- | --------: | --------: |
| Array | 240.69 ns | 288.55 ns |
| List | 1.32 ms | 213.65 µs |
The array case is a hair slower — it now allocates the candidate through an
array spread instead of returning a shared empty literal — and in exchange the
`k == n` special case added in #4208 is gone, since taking a zero-length prefix
already costs nothing.
The benchmark goes back to 10,000 elements; #4208 had to lower it to 1,000
precisely because of the bug this fixes.
Reviewed by Codex CLI together with the preceding test commit: "Verified
ordering, exact size hints, non-divisible lengths, `k == n` without element
copying, and cursor compatibility with single-use iterators. Independent
old/new models agree for 5,050 input pairs."
Signed-off-by: Codex CLI <codex@openai.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jtBJHK749cpStav5ZMNCr1 parent 6d03c2a commit ff70d6c
2 files changed
Lines changed: 33 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
29 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
30 | 33 | | |
31 | 34 | | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
39 | 45 | | |
40 | 46 | | |
41 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
42 | 52 | | |
43 | 53 | | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
51 | 64 | | |
52 | 65 | | |
53 | 66 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
| 16 | + | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
| 22 | + | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
0 commit comments