{
"$type": "site.standard.document",
"content": "---\ntitle: \"Extempore is alive on aarch64 (part deux)\"\ndescription: \"CI green on four platforms, a migration from TinyScheme to s7, and a 9x\n compiler speedup from hash table caches and union-find type unification.\"\ntags:\n - extempore\n---\n\nA quick update on\n[Extempore on aarch64](/blog/2025/12/17/extempore-s-aliiiiive-on-aarch64/):\n\n- [CI is now green](https://github.com/digego/extempore/actions) on macOS,\n Windows, and _two_ Linux architectures (aarch64 and x64)\n- OpenGL graphics stuff is (soft) deprecated because that's increasingly tricky\n to maintain and keep up-to-date, but there are\n [a couple of new WebGPU examples](https://github.com/digego/extempore/tree/aarch64/examples/external);\n the\n [shadertoy one](https://github.com/digego/extempore/blob/aarch64/examples/external/shadertoy.xtm)\n is kind of fun (no full \"xtmrender\" pipeline yet, and no ETA on that\n unfortunately)\n- along the way I wrote a\n [tree-sitter grammar](https://github.com/extemporelang/tree-sitter-extempore)\n for extempore (Scheme + xtlang) and some _very_ hacked-together support for\n evaling code in [helix](https://helix-editor.com) (which\n [I'm using these days](/blog/2026/02/18/ben-s-dev-setup-2026-edition/))\n- there's now\n [a repl](https://github.com/digego/extempore/commit/c76be4d24e3315cc80acb1a244fda6aff7003bce),\n although only on macOS/Linux at the moment\n- [upgraded to LLVM 22](https://github.com/digego/extempore/commit/1dcdaf94d1)\n (from 21), which went surprisingly smoothly\n- I'm part-way through updating the docs website (bringing it into the\n [`docs/` folder in the main extempore repo](https://github.com/digego/extempore/tree/aarch64/docs))\n\n## Compiler guts\n\n**NOTE: these compiler & Scheme changes are in a couple of standalone commits\nand could be reverted in future... experimental stuff. But fun!**\n\nThe biggest under-the-hood change is a\n[refactor of the xtlang compiler](https://github.com/digego/extempore/commit/93dacf79)\nand a migration from TinyScheme to\n[s7 Scheme](https://ccrma.stanford.edu/software/snd/snd/s7.html)---Bill\nSchottstaedt's embeddable Scheme interpreter from CCRMA. s7 was originally\nforked from TinyScheme anyway, so the migration path was relatively\nstraightforward, but it's a much more capable interpreter with proper hash\ntables, first-class environments, and better performance across the board.\n\nOn the compiler side, the old xtlang type checker used assoc-list caches for\neverything---which was fine when type environments were small, but scaled poorly\nfor libraries with heavy generic instantiation. The refactored compiler replaces\nthose with hash table caches, adds union-find for type unification, and moves to\nconstraint-based solving.\n\nHere are ahead-of-time compilation benchmarks for all the core and external\naudio libraries[^bench-setup]:\n\n| Library | Before | After | Speedup |\n| ----------------------------------- | ---------: | --------: | --------: |\n| `libs/base/base.xtm` | 5.59s | 3.24s | 1.7x |\n| `libs/core/math.xtm` | 16.57s | 4.04s | 4.1x |\n| `libs/core/rational.xtm` | 6.47s | 3.47s | 1.9x |\n| `libs/core/audiobuffer.xtm` | 7.45s | 3.49s | 2.1x |\n| `libs/core/audio_dsp.xtm` | 32.14s | 5.71s | 5.6x |\n| `libs/core/instruments.xtm` | 109.83s | 8.38s | **13.1x** |\n| `libs/external/fft.xtm` | 5.71s | 3.99s | 1.4x |\n| `libs/external/sndfile.xtm` | 9.17s | 3.64s | 2.5x |\n| `libs/external/audio_dsp_ext.xtm` | 5.51s | 4.28s | 1.3x |\n| `libs/external/instruments_ext.xtm` | 12.57s | 9.26s | 1.4x |\n| `libs/external/portmidi.xtm` | 4.86s | 3.35s | 1.5x |\n| **Total** | **215.9s** | **52.9s** | **4.1x** |\n\nThe headline number is a 4.1x wall-clock speedup, but each invocation includes\n~3s of startup overhead (there's a hard-coded `sleep` for NSApp initialisation\nbecause reasons). Subtracting that out, the pure compile time went from ~183s to\n~20s---a **9x speedup**.\n\nThe standout is `instruments.xtm` at 13.1x; it's a longer file and works the\ncompiler more than some of the others, which is exactly where the new union-find\nand hash table caches pay off. Libraries showing more modest improvements\n(1.3--1.5x) are dominated by LLVM JIT time and startup overhead rather than\nScheme-level type checking, so there's not much to squeeze out of those on the\ncompiler side.\n\n[^bench-setup]:\n Benchmarked on Linux x86_64 (AMD Zen 4) with LLVM 22.1.0 and ORC JIT. Each\n library compiled in a separate `extempore --nobase --batch` process.\n \"Before\" is commit `44b7b5c5` (TinyScheme, assoc-list caches); \"After\" is\n commit `93dacf79` (s7 Scheme, hash table caches + union-find + constraint\n solver).\n\nThis is still all on the\n[aarch64 branch](https://github.com/digego/extempore/tree/aarch64); I'm not\nready to merge to master just yet. If you're an extempore user willing to get\nyour hands a little dirty, try building from source on the tip of that branch\nand running your extempore workloads---I'd appreciate that, including bug\nreports of things that don't work.\n",
"createdAt": "2026-05-13T23:14:39.742Z",
"description": "CI green on four platforms, a migration from TinyScheme to s7, and a 9x compiler speedup from hash table caches and union-find type unification.",
"path": "/blog/2026/02/26/extempore-is-alive-on-aarch64-part-deux",
"publishedAt": "2026-02-26T00:00:00.000Z",
"site": "at://did:plc:tevykrhi4kibtsipzci76d76/site.standard.publication/self",
"tags": [
"extempore"
],
"textContent": "CI green on four platforms, a migration from TinyScheme to s7, and a 9x compiler speedup from hash table caches and union-find type unification.",
"title": "Extempore is alive on aarch64 (part deux)"
}