# The instructions that each case retires for each step of `N` on macOS on Apple silicon, the only platform with these counts. `tests/test_instructions.py` checks them with `basedpl.bpltests.instruction_budgets`.
# Instruction counts don't change with load or code layout. The cases that make one call per step repeat within about 0.2%, and those that map over 64 cells within about 1%. They show changes of a few percent per call or per cell, which costs in copies can't.
# A case fails when it retires more than 3% more, or more than 3% fewer, instructions than its count. The change that makes a call cheaper also lowers each count it moves. A new compiler version can inline differently and move the counts. After one, set them again from `bpl-tests instruction_budgets`.
[setup]
fib←{⍵<2ₓ?⍵;(∇⍵-1ₓ)+∇⍵-2ₓ} ⋄ g←{⍵<2ₓ?⍵;(g ⍵-1ₓ)+g ⍵-2ₓ} ⋄ k←0 ⋄ t←64⍴"ab" "cde" ⋄ m←[0 1⋄¯1 0] ⋄ s←[64 2 2]⍴$t $f $f $t $t $t $f $t ⋄ v_4←1.5 2.5 3.5 4.5
[calls]
# A primitive call.
+⍣N 0	392
# A dfn call that returns its argument.
{⍵}⍣N 0	1372
# A dfn that reads a global.
{⍵+k}⍣N 0	2499
# A local assignment and read.
{x←⍵+1 ⋄ x}⍣N 0	2970
# A spaced run that applies a train at once. The compiled statement calls the train's tines in place, without building the train (`Op::CallTrain`).
{(⍵)+⊢ ⍵}⍣N 0	3844
# A bracket literal. It counted 5,620 on 24 October 2026. Joining its items' kinds, fixedness and weakness in `Promoted::join` added about 125 instructions. The memory guard's check on each allocation and the later promotion refactor added about 95 more. Moving `other_step` out of line and the `Value::Pending` arms in the resolving functions added about 220 more.
{↑[⍵ 1]}⍣N 0	5941
# A fixed mark on a 4-item float vector, which floors each item to `i32` through `derivative::converted`, the entry point that marks on values and on functions share. Stage 3's step 6 sent value marks there, which cost about 215 instructions. The inline size test in `fusion::convert` and the inline tests of `Value::carried` and `Value::holds_values` recover about 100 of them. On 26 October 2026, single-stepping `binder::derived` under lldb counted every instruction that it and its calls retire. Outside `malloc`, the other 115 lay in four functions: 130 in `derivative::converted`, 17 in an out-of-line `product` for its size test's length, 15 in `Value::converted`'s dispatch, and 47 fewer in `binder::derived`, which no longer reads the settings itself. Of the 130, about 45 read the settings, 25 test for carriers and 12 make the size test. The inline `rustymath::layout::count` and an always-inlined `derivative::plain` then saved 19.
v_4ₓ₄	3733
# `fib 10ₓ` makes 177 calls, which read `⍵` and `∇`.
{fib 10ₓ}⍣N 0	824136
# `g 10ₓ` makes 177 calls of a dfn that calls itself by name, with spaces that split its statement into runs. Each call applies a train at once, whose tines the compiled statement calls in place (`Op::CallTrain`).
{g 10ₓ}⍣N 0	914096
# `fib 10ₓ` under static kinds, whose integer scalar calls run their integer kernel at the `int` width (`Primitive::integer_kernel`).
•prefs ["kinds":"static"] ⋄ {fib 10ₓ}⍣N 0	870789
# `fib 10ₓ₂` on 16-bit fixed integers, whose scalar calls run their integer kernel at that width (`Primitive::fixed_number`), and whose comparisons compare the integers directly (`Number::order`).
{fib 10ₓ₂}⍣N 0	905540
# Each over the 64 strings in `t`, of two lengths, reverses them as ragged cells: one walk of each string's plan over their leaf (`batch::segment_remap`), with the batched run's framing and assembly.
⌽¨⍣N t	201391
# Rank's general path calls a dfn once for each of the same 64 cells.
{⌽⍵}⍤0⍣N t	316700
# A system function that converts each item on its own runs once on the leaf of the same 64 strings (`batch::leaf_system`).
•ucs⍣N t	39813
# A 2×2 float matrix product.
{m+.×m}⍣N 0	6500
# Rank on a stack of 64 Boolean 2×2 matrices, which runs one or-and product for the whole stack.
{∨.∧⍤2⍨s}⍣N 0	27500
# `∂` of a dfn on 4 floats, whose later calls replay the program that its first call traced.
loss←{+/⊼1-2×⍵} ⋄ {loss∂v_4 ⋄ ⍵}⍣N 0	11366
# The same on 16 floats. At this size a replay costs the same per call.
loss←{+/⊼1-2×⍵} ⋄ v_16←1.5+⍳16 ⋄ {loss∂v_16 ⋄ ⍵}⍣N 0	11421
# `∂` with no program. A guard on `⍵` stops the first call's trace ("a read of a traced value"). Each call then runs through duals, a linear record and its transpose (`linear::transpose`). The count includes the guard's `+/` and `<`.
guarded←{0<+/⍵ ? +/⊼1-2×⍵ ; 0} ⋄ {guarded∂v_4 ⋄ ⍵}⍣N 0	134404
# The same on 16 floats.
guarded←{0<+/⍵ ? +/⊼1-2×⍵ ; 0} ⋄ v_16←1.5+⍳16 ⋄ {guarded∂v_16 ⋄ ⍵}⍣N 0	135907
# `⇄` by L-BFGS on Rosenbrock's function: 53 evaluations, about 153,500 instructions each. Each evaluation calls `linearized` directly, outside the program cache.
rosen←{[x y]←⍵ ⋄ ⊼1-x + 100×⊼y-⊼x} ⋄ {rosen⇄ ¯1.2 1 ⋄ ⍵}⍣N 0	8136698
# Stage 8's baselines (one-graph plan, "Stage 8's tests and records"), counted on build `27541f5c` of 31 October 2026, before the stage's first edit. Selective assignment through a selecting function on 4 floats. The target `1↑a` runs under a `Label` level on the simple root `a`, whose labels hold a mapping and no ids. `Selection::write_into` writes `⍵` at the position that the labels give.
a←v_4 ⋄ {(1↑a)←⍵ ⋄ ⍵}⍣N 0	20856
# Under with a selecting function on the same kind of root. `1↑` runs under a `Label` level and `2×` on its result. `Selection::write_into` writes that result at the position that the labels give.
{(2×)@(1↑)v_4 ⋄ ⍵}⍣N 0	23534
