whitepaper: first machine-checked EML + 3-way i5-8350U benchmark
Two landings fox requested. §8.6 EML verification section gains a "First machine-checked treatment" paragraph. Sub-agent WebFetched arXiv:2603.21852v2 and confirmed Odrzywołek's original paper is pure LaTeX prose with no formal tool; the Zenodo companion is symbolic-regression code, not a verification artifact. Our Lean 4 proof appears to be the first machine-checked EML formalization — five theorems, zero `sorry`, no Mathlib dependency, 40× faster than the brute-force numerical search. §6.4 "Three Implementations Head-to-Head" is new — benchmark numbers from the actual i5-8350U hardware, collected via in- process `current-time-ms` timing on each impl: sum-to(100k) asm 74 ms < C 121 ms < Python-fast 583 ms sum-to(1M) asm 734 ms < C 1.2 s < Python-fast 5.4 s ackermann(3,8) asm 2.4 s < Python-fast 18.5 s (C segfaults) asm beats every other impl on every measurable workload. The C interpreter segfaults on ack(3,8) — its evaluator uses the host C stack, and deep recursion exhausts it. asm and Python-fast use explicit frame storage and handle deep recursion cleanly. Also documents what I tried and backed off: - asm env-lookup inline cache: upper bound ~5% win, not 20-40%, because asm chains are typically 2 deep. Parked. - asm's real bottleneck is `env_define` allocating 24 bytes per parameter per call — 48 MB for sum-to(1M). Future optimization: per-frame batched allocation or self-tail-call env reuse. Profiling done on the real hardware. No inline-cache code change landed; the finding itself is the commit.
This commit is contained in:
parent
d13293469c
commit
33de120fef
2 changed files with 1189 additions and 934 deletions
File diff suppressed because one or more lines are too long
|
|
@ -385,6 +385,26 @@ The important comparison is not uncommonlisp vs CPython (different languages), b
|
|||
- **mergesort**: Recursive divide-and-conquer on 200 elements. Tests ``cons`` allocation throughput
|
||||
- **hash-table**: 1,000 ``set!`` + ``ref`` operations. Tests Python dict interop overhead
|
||||
|
||||
6.4 Three Implementations Head-to-Head (i5-8350U)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Same hardware, same workloads, in-process timing via ``current-time-ms``. Best of two runs.
|
||||
|
||||
.. table::
|
||||
:widths: 26 18 18 18
|
||||
|
||||
======================== =========== =========== ===========
|
||||
Benchmark Python fast C asm
|
||||
======================== =========== =========== ===========
|
||||
sum-to(100 000) 583 ms 121 ms **74 ms**
|
||||
sum-to(1 000 000) 5,432 ms 1,200 ms **734 ms**
|
||||
fib(35) iterative ~0 ms ~0 ms ~0 ms
|
||||
ackermann(3, 8) = 2045 18,479 ms (segfault) **2,383 ms**
|
||||
======================== =========== =========== ===========
|
||||
|
||||
asm wins every measurable workload on this hardware. The C interpreter segfaults on ackermann(3, 8) because its evaluator uses the host C stack for Scheme frames; ackermann recurses thousands of levels deep. asm and Python-fast both use explicit frame storage and handle the recursion cleanly. asm beats Python-fast by ~7× on ``sum-to(1M)`` and ~8× on ``ackermann(3, 8)`` despite asm being a tree-walker with no JIT — the constant-factor difference from eliminating Python's dict lookups, stack frames, and GC coordination is large.
|
||||
|
||||
**asm's remaining bottleneck is allocation, not lookup.** Profiling ``sum-to(1M)`` shows ~170 MB RSS — each tail call through ``apply_closure`` + ``env_define`` allocates 24 bytes per parameter (sym / val / parent), twice per ``loop`` iteration, for 48 MB total before the three ``heap_grow`` events that follow. A future optimization candidate is per-frame batched allocation (``8 + 16N`` bytes once per call instead of ``24N``), or env-cell in-place reuse for self-tail-calls. An inline cache for env lookups (ported from Python's VM) turns out to help less than anticipated because asm's env chains are typically only 2 deep and each step is a pointer dereference; measured upper bound is ~5%.
|
||||
|
||||
7. Portal: Feedback Across Time
|
||||
----------------------------------------
|
||||
|
|
@ -652,6 +672,8 @@ The numerical approaches enumerate all pairwise EML compositions at each depth,
|
|||
|
||||
The Lean proof operates over abstract ``exp`` & ``ln`` functions with the axioms ``exp(ln(x)) = x``, ``ln(exp(x)) = x``, & ``ln(1) = 0``. This makes the result independent of any particular real number implementation.
|
||||
|
||||
**First machine-checked treatment.** The original paper (Odrzywołek, arXiv:2603.21852v2, 2026-04-04) presents the EML universality claim analytically — pure LaTeX mathematics, no formal tool. The companion Zenodo artifact is symbolic-regression / gradient-optimization code, not a verification. To our knowledge the Lean 4 proof shipped in this repo is the first machine-checked treatment of the EML identities. Five theorems, zero ``sorry``, no Mathlib dependency — 40× faster than the brute-force numerical search it replaced, and carrying the additional guarantee that no implementation quirk of floating point can ever break the conclusion.
|
||||
|
||||
|
||||
9. Language Coverage
|
||||
---------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue