Lean Kernel Arena / perf/shift-cascade

Test "perf/shift-cascade"

Expected: 👍 accept · Size: 256.3 KB · Lines: 5.1 k · lean4export: 3.1.0 · Lean: 4.29.0 · 📄 Declaration · 🔗 Source

Stress test for cascading substitution overhead in kernel let processing.

N nested let bindings inside a lambda, where each value references the outer lambda parameter and the previous binding:

fun (a : Nat → Nat) => let f₁ := fun x => a x let f₂ := fun x => a (f₁ x) ... let fₙ := fun x => a (fₙ₋₁ x) fₙ 0

The kernel processes each let by substituting the value into the body. Each value has a free bvar (references a), so substitution under inner binders creates shifted copies. In a de Bruijn kernel with deferred shifts, these Shift(val, offset) wrappers accumulate: step k must traverse through O(k) wrappers from previous steps, giving O(N²) total work.

A locally-nameless kernel substitutes fvars that need no shifting, giving O(N) total.

N=1000 in the Lean source. Increase to stress further.

Checker Result ⏱️ 🧠
nanoda 👍 8 ms (-84%) 4.1 MB
official-nightly 👍 52 ms (-3%) 58.4 MB
official 👍 54 ms (0%) 66.7 MB
official-v4.28.0 👍 60 ms (+11%) 71.8 MB
nanobruijn 👍 204 ms (+279%) 66.2 MB
lean4lean 👍 84 ms (+55%) 92.9 MB
mini 👍 1.8 s (+3285%) 70.5 MB
always-decline 🚫 1 ms 2.8 MB
always-reject 1 ms 2.8 MB
rpylean 👍 14 ms (-75%) 14.8 MB
parse-only 👍 55 ms (+2%) 70.0 MB
always-accept 👍 1 ms (-99%) 2.8 MB