Lean Kernel Arena / perf/let-ladder

Test "perf/let-ladder"

Expected: 👍 accept · Size: 457.3 KB · Lines: 10.4 k · lean4export: 3.1.0 · Lean: 4.29.1 · Timeout: 50.0 s · 📄 Declaration · 🔗 Source

The declaration to check has type Nat and value

let x₃ := 0; x₃ + (let x₂ := 0; x₂ + (let x₁ := 0; x₁ + (x₃ + (x₂ + (x₁ + 0)))))

shown at n=3: n let bindings, each separated from the next by an addition, over an innermost sum that names every binding.

Substituting a binding into the body before checking it traverses O(n) nodes at each of the n bindings, for Θ(n²) in time and in allocated nodes. Recording the binding and reading it where the body names it costs O(1) per binding, for Θ(n).

The additions are what keep the bindings apart: a run of adjacent lets could be opened by a single substitution; not so here. Nat.add is the only application head, so no beta reduction is involved.

N=2000 in the Lean source.

Checker Result ⏱️ 🧠
mathgraph 👍 142 ms (÷7.1) 93.6 MB (÷3.4)
sokonanoda 👍 142 ms (÷7.1) 91.3 MB (÷3.5)
nanoclo 👍 6 ms (÷183) 65.5 MB (÷4.9)
con-ron 👍 762 ms (-25%) 520.7 MB (+63%)
lazylean 👍 366 ms (÷2.8) 36.5 MB (÷8.8)
nanoda 👍 698 ms (-31%) 306.1 MB (-4%)
nanobruijn 👍 1.7 s (+64%) 824.9 MB (×2.6)
con-leche 👍 479 ms (÷2.1) 234.0 MB (-27%)
eink0rn 👍 1.5 s (+44%) 375.0 MB (+17%)
ind-models 👍 1.1 s (+4%) 352.4 MB (+10%)
official 👍 1.0 s (0%) 319.8 MB (0%)
lean4lean 👍 1.0 s (+2%) 349.1 MB (+9%)
tenet 👍 1.7 s (+69%) 330.5 MB (+3%)
nanoclo-fortran 👍 21 ms (÷48) 13.1 MB (÷24)
lean4cobol 👍 17.1 s (×17) 420.6 MB (+32%)
evmlean 🚫 8.2 s 281.0 MB
mini 👍 1.3 s (+28%) 1023.9 MB (×3.2)
overfull 💥 1.6 m 48.8 MB
kiota 👍 585 ms (-42%) 528.2 MB (+65%)
canonical-min 🚫 778 ms 1.2 GB
rpylean ✋ 386 ms 329.3 MB
vow-lean-kernel 👍 31.6 s (×31) 525.7 MB (+64%)
official-v4.28.0 👍 1.1 s (+11%) 325.3 MB (+2%)
still-nanoda 👍 634 ms (-37%) 306.1 MB (-4%)
nyaya 💥 4.3 s 717.9 MB
parse-only 👍 53 ms (÷19) 68.2 MB (÷4.7)