Test "perf/app-lam"
Expected: 👍 accept · Size: 1.2 MB · Lines: 28.6 k · lean4export: 3.1.0 · Lean: 4.29.0 · 📄 Declaration · 🔗 Source
A synthetically generated term with n levels of alternating applications and lambdas, with DAG sharing.
At each level, a constant is applied to two identical lambda arguments. The export format records these as a single shared expression (DAG). Each lambda body grows with the nesting depth, referencing all enclosing binders.
This tests two aspects of checker performance:
Infer cache: Since both arguments at each level are the same expression, a checker without an infer cache re-infers the type of each shared subterm, doubling work at every level — O(2ⁿ) total.
Substitution cost: Even with a cache, type-inferring each lambda requires substituting into its body (size O(n)) at each of the n levels, giving O(n²) total. Whether this cost arises depends on the checker's binder representation.
| Checker | Result | ⏱️ | 🧠 | ||
|---|---|---|---|---|---|
| nanoda | 👍 | 4.8 s | (-10%) | 2.1 GB | (+48%) |
| nanobruijn | 👍 | 40 ms | (-99%) | 18.2 MB | (-99%) |
| official-nightly | 👍 | 5.4 s | (0%) | 1.4 GB | (-1%) |
| official | 👍 | 5.4 s | (0%) | 1.4 GB | (0%) |
| official-v4.28.0 | 👍 | 5.4 s | (0%) | 1.4 GB | (0%) |
| lean4lean | 👍 | 5.4 s | (+1%) | 1.4 GB | (+2%) |
| mini | 💥 | 32.3 s | 74.4 MB | ||
| always-decline | 🚫 | 1 ms | 2.8 MB | ||
| always-reject | ✋ | 1 ms | 2.8 MB | ||
| rpylean | 👍 | 41 ms | (-99%) | 18.6 MB | (-99%) |
| parse-only | 👍 | 115 ms | (-98%) | 72.0 MB | (-95%) |
| always-accept | 👍 | 1 ms | (-100%) | 2.8 MB | (-100%) |