{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/lobste-rs/2026-10-06-janet-on-x32-32-bit-pointers-64-bit-speed-25-less-ram/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "* * *\n\n> It’s possible to save a dramatic amount of memory (close to half for programs with pointer heavy heaps) and also speed up programs by a modest amount (by way of more data fitting in cache) by using 32 bit pointers on 64 bit systems.\n>\n> The Linux x32 ABI lets you do just this, but it’s tragically underused and overlooked. It’s disabled by default on Debian (though you can enable it with a boot flag) and not even compiled in on Arch Linux. Most software compiles just fine for x32, but there isn’t much packaging for it so you do have to compile nearly everything yourself.\n>\n> I experimented with deploying mastodon on x32 and it cut the app’s memory usage from 650mb to 350mb. There’s so much potential here, but the work is mostly of the thankless coordination and communication type and I don’t have the time or motivation to push it forward myself. - [Hailey](https://lobste.rs/s/gns27z/what_are_your_programming_hunches_you#c_tw3vok)\n\n### How to Compile for 32 Bits?\n\nJanet libraries like Spork supply their own build flags, but we can hijack them with a fake `cc` which starts the real one with the necessary `-m32 -msse2 -mfpmath=sse` flags. I modified the beginning of my default [Janet build script](https://codeberg.org/veqq/install-latest-janet/src/branch/master/install-latest-janet.sh):\n\n```bash\n#!/bin/sh\nset -eu\n\nTARGET=\"$PWD/janet32\"\nJANET=\"$TARGET/bin/janet\"\n\nmkdir -p \"$TARGET/cc32\"\nprintf '#!/bin/sh\\nexec gcc -m32 -msse2 -mfpmath=sse \"$@\"\\n' > \"$TARGET/cc32/cc\"\nchmod +x \"$TARGET/cc32/cc\"\nexport PATH=\"$TARGET/cc32:$PATH\"\nexport JANET_TOOLCHAIN=cc\n\nunset JANET_PATH JANET_TREE\n\nmkdir -p \"$TARGET\"\ncd \"$TARGET\"\nrm -rf build/spork janet\n\ngit clone https://github.com/janet-lang/janet\ncd janet\n```\n\nEasy enough! Now let’s try it!\n\n### Failing on Arch\n\ntl;dr: 20% memory reduction, 50% slower\n\nSee the Scripts and Results\n\nThis is on cachyos (arch, btw) with lib32-glibc lib32-gcc-libs. Adding this to a build script forces libraires like spork to build at 32 bit too!\n\nFor `mem.janet`:\n\n```janet\n(let [live @[]]\n  (for i 0 2_000_000\n    (array/push live [i (+ i 1)]))\n  (gccollect)\n  (print (length live)))\n```\n\nNote, these use Fish and I don’t want to rebuild my site with other language support:\n\n```bash\nsudo pacman -S time # different from just time\ncommand time -v ./bin/janet mem.janet # command skips the fish version\ncommand time -v ./janet32/bin/janet mem.janet\n\n2000000\n       Command being timed: \"./bin/janet mem.janet\"\n       User time (seconds): 0.24\n       System time (seconds): 0.05\n       Percent of CPU this job got: 100%\n       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.30\n       Average shared text size (kbytes): 0\n       Average unshared data size (kbytes): 0\n       Average stack size (kbytes): 0\n       Average total size (kbytes): 0\n       Maximum resident set size (kbytes): 145196\n       Average resident set size (kbytes): 0\n       Major (requiring I/O) page faults: 0\n       Minor (reclaiming a frame) page faults: 33513\n       Voluntary context switches: 1\n       Involuntary context switches: 9\n\n2000000\n       Command being timed: \"./janet32/bin/janet mem.janet\"\n       User time (seconds): 0.47\n       System time (seconds): 0.03\n       Percent of CPU this job got: 99%\n       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.50\n       Average shared text size (kbytes): 0\n       Average unshared data size (kbytes): 0\n       Average stack size (kbytes): 0\n       Average total size (kbytes): 0\n       Maximum resident set size (kbytes): 113716\n       Average resident set size (kbytes): 0\n       Major (requiring I/O) page faults: 0\n       Minor (reclaiming a frame) page faults: 25686\n       Voluntary context switches: 1\n       Involuntary context switches: 21\n```\n\nI added a 0 in the test\n\n```bash\ncommand time -v ./bin/janet mem.janet\n                  command time -v ./janet32/bin/janet mem.janet\n20000000\n        Command being timed: \"./bin/janet mem.janet\"\n        User time (seconds): 2.83\n        System time (seconds): 0.46\n        Percent of CPU this job got: 99%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.31\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 1410668\n        Average resident set size (kbytes): 0\n        Major (requiring I/O) page faults: 0\n        Minor (reclaiming a frame) page faults: 316820\n        Voluntary context switches: 1\n        Involuntary context switches: 164\n        Exit status: 0\n20000000\n        Command being timed: \"./janet32/bin/janet mem.janet\"\n        User time (seconds): 4.64\n        System time (seconds): 0.35\n        Percent of CPU this job got: 99%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.00\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 1098372\n        Average resident set size (kbytes): 0\n        Major (requiring I/O) page faults: 0\n        Minor (reclaiming a frame) page faults: 238633\n        Voluntary context switches: 1\n        Involuntary context switches: 193\n```\n\nFor e.g. `declarative-dsls/tests.janet`\n\n```bash\n98 passed\n        Command being timed: \"./bin/janet ./lib/janet/bin/judge declarative-dsls/tests.janet\"\n        User time (seconds): 0.42\n        System time (seconds): 0.02\n        Percent of CPU this job got: 100%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.45\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 61900\ndeclarative-dsls/tests.janet\n\n98 passed\n        Command being timed: \"./bin/janet ./lib/janet/bin/judge declarative-dsls/tests.janet\"\n        User time (seconds): 0.70\n        System time (seconds): 0.02\n        Percent of CPU this job got: 99%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.72\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 54108\n        Average resident set size (kbytes): 0\n        Major (requiring I/O) page faults: 0\n        Minor (reclaiming a frame) page faults: 12735\n```\n\nAs Hailey said, Arch does not come with the [x32 ABI](https://en.wikipedia.org/wiki/X32_ABI) compiled, so I had to use `-m32` and while we do get a 20% memory savings, we execute 50% slower because half the registers aren’t used! `-m32` is the old 32-bit x86 mode using only 8 registers. To see the speed-up, we need to use `-mx32` which uses the 64-bit instruction set with shrunken 32-bit pointers. But I don’t want to recompile Linux…\n\nUnfortunately, Ubuntu also dropped x32 support.\n\n### Winning on Deprecated Ubuntu\n\nLuckily, lazily, I have access to some deprecated servers (*of course* not in prod…) and OS installs, wasting hard disk space:\n\n> Ubuntu 20.04 LTS Focal Fossa has reached its end of standard support on 31 May 2025.\n\nUbuntu, so we have bash again:\n\n```bash\ngrep X86_X32 /boot/config-$(uname -r)  \nCONFIG_X86_X32=y\n```\n\nJust what we need, although `gcc version 9.4.0` is a bit old. We already have `build-essential git gcc-multilib libc6-dev-x32`. We are ready to soar! Here is our full `32janet.sh`:\n\n```bash\n#!/bin/bash\nset -eu\n\nTARGET=\"$PWD/janetx32\"\nJANET=\"$TARGET/bin/janet\"\n\nmkdir -p \"$TARGET/cc32\"\n# this forces Janet C libraries like Spork to build with 32bit also\n# FFI build test fails on -mx32 build so -DJANET_NO_FFI\nprintf '#!/bin/sh\\nexec gcc -mx32 -DJANET_NO_FFI \"$@\"\\n' > \"$TARGET/cc32/cc\"\nchmod +x \"$TARGET/cc32/cc\"\nexport PATH=\"$TARGET/cc32:$PATH\"\nexport JANET_TOOLCHAIN=cc\n\nunset JANET_PATH JANET_TREE\nmkdir -p \"$TARGET\"\ncd \"$TARGET\"\n\ngit clone https://github.com/janet-lang/janet\ncd janet\n\nexport CFLAGS='-fPIC -O3 -flto -fno-semantic-interposition -march=native' # speed gains\nPREFIX=\"$TARGET\" make clean\nPREFIX=\"$TARGET\" make\nPREFIX=\"$TARGET\" make test\nPREFIX=\"$TARGET\" make install\n\ncd ..\ngit clone --depth=1 https://github.com/janet-lang/spork build/spork\n\"$JANET\" -e '(if (bundle/installed? \"spork\") (bundle/replace \"spork\" \"build/spork\") (bundle/install \"build/spork\"))'\n\n# ### Packages\nPM=\"$TARGET/lib/janet/bin/janet-pm\"\ngit clone https://codeberg.org/veqq/declarative-dsls\n\"$JANET\" \"$PM\" install file::declarative-dsls # also does https://codeberg.org/veqq/varray\ngit clone https://github.com/ianthehenry/judge # also does https://github.com/ianthehenry/cmd\n\"$JANET\" \"$PM\" install file::judge\n\ntime \"$JANET\" \"$TARGET/lib/janet/bin/judge\" declarative-dsls/tests.janet # to show that it worked\n```\n\nAnd a \\`64janet.sh to compare it with:\n\n```bash\n#!/bin/bash\nset -eu\n\nTARGET=\"$PWD/janet64\"\nJANET=\"$TARGET/bin/janet\"\nunset JANET_PATH JANET_TREE\nmkdir -p \"$TARGET\"\ncd \"$TARGET\"\n\ngit clone https://github.com/janet-lang/janet\ncd janet\n\nexport CFLAGS='-fPIC -O3 -flto -fno-semantic-interposition -march=native' # speed gains\nPREFIX=\"$TARGET\" make clean\nPREFIX=\"$TARGET\" make\nPREFIX=\"$TARGET\" make test\nPREFIX=\"$TARGET\" make install\n\ncd ..\ngit clone --depth=1 https://github.com/janet-lang/spork build/spork\n\"$JANET\" -e '(if (bundle/installed? \"spork\") (bundle/replace \"spork\" \"build/spork\") (bundle/install \"build/spork\"))'\n\n# ### Packages\nPM=\"$TARGET/lib/janet/bin/janet-pm\"\ngit clone https://codeberg.org/veqq/declarative-dsls\n\"$JANET\" \"$PM\" install file::declarative-dsls # also does https://codeberg.org/veqq/varray\ngit clone https://github.com/ianthehenry/judge # also does https://github.com/ianthehenry/cmd\n\"$JANET\" \"$PM\" install file::judge\n\ntime \"$JANET\" \"$TARGET/lib/janet/bin/judge\" declarative-dsls/tests.janet # to show that it worked\n```\n\nNow we compare them:\n\n```bash\nsudo apt install time # different from just time\n/usr/bin/time -f '%e s  %M KB' janet64/bin/janet janet64/lib/janet/bin/judge janet64/declarative-dsls/tests.janet\n/usr/bin/time -f '%e s  %M KB' janetx32/bin/janet janetx32/lib/janet/bin/judge janetx32/declarative-dsls/tests.janet\n\n2.42 s  61668 KB # 64bit\n2.36 s  53472 KB # 32bit\n```\n\nBut [declarative-dsls](https://codeberg.org/veqq/declarative-dsls) is a worst case scenario, using [typed c arrays](https://codeberg.org/veqq/varray) for big speed ups, which don’t benefit much from this. Lets make some minimal benchmarks to really test the differences:\n\nSee the Benchmarks Scripts\n\n`words.janet` builds a text, splits it into words, counts them and sorts on that:\n\n```janet\n(let [start (os/clock :monotonic)\n      rng (math/rng 42)\n      vocab (seq [i :range [0 5000]] (string \"w\" (math/rng-int rng 100000)))\n      text @\"\"\n      counts @{}]\n  (repeat 600000 (buffer/push text (in vocab (math/rng-int rng 5000)) \" \"))\n  (each word (string/split \" \" text)\n    (put counts word (+ 1 (get counts word 0))))\n  (pp (take 3 (sort-by |(- (in $ 1)) (pairs counts))))\n  (print (length counts) \" distinct words\")\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\n`records.janet` groups structs by department and summarizes those departments, with unused extra fields like real code:\n\n```janet\n(let [start (os/clock :monotonic)\n      rng (math/rng 7)\n      depts [:eng :ops :sales :legal :support]\n      people (seq [i :range [0 300000]]\n               {:id i\n               # :name and :tags not used\n                :name (string \"person-\" i)\n                :dept (in depts (math/rng-int rng 5))\n                :salary (+ 30000 (math/rng-int rng 90000))\n                :tags [(math/rng-int rng 10) (math/rng-int rng 10)]})\n      by-dept (group-by |(in $ :dept) people)]\n  (each dept (sorted (keys by-dept))\n    (let [staff (in by-dept dept)\n          salaries (map |(in $ :salary) staff)]\n      (pp [dept\n           (length staff)\n           (math/round (/ (sum salaries) (length staff)))\n           (length (filter |(> $ 100000) salaries))])))\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\n`parse.janet` parses lines with a PEG and totals them:\n\n```janet\n(let [start (os/clock :monotonic)\n      rng (math/rng 3)\n      lines (seq [i :range [0 200000]]\n              (string i \",\" (math/rng-int rng 1000) \",item-\" (math/rng-int rng 500) \",\" (/ (math/rng-int rng 10000) 100)))\n      row (peg/compile\n            ~{:num (number (some (set \"0123456789.\")))\n              :txt (capture (some (if-not \",\" 1)))\n              :main (* :num \",\" :num \",\" :txt \",\" :num -1)})\n      rows (map |(peg/match row $) lines)\n      totals @{}]\n  (each [id qty item price] rows\n    (put totals item (+ (get totals item 0) (* qty price))))\n  (print (length rows) \" rows, \" (length totals) \" items, total \" (math/round (sum (values totals))))\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\n`tree.janet` builds and walks binary trees, our pointer-heaviest example:\n\n```janet\n(let [start (os/clock :monotonic)\n      make (fn make [depth]\n             (if (= depth 0)\n               [nil nil]\n               [(make (- depth 1)) (make (- depth 1))]))\n      check (fn check [node]\n              (if (in node 0)\n                (+ 1 (check (in node 0)) (check (in node 1)))\n                1))\n      long-lived (make 19)]\n  (var total 0)\n  (repeat 40 (+= total (check (make 14))))\n  (print total \" \" (check long-lived))\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\nWe benchmark:\n\n```bash\nfor f in words records tree parse; do  \n>   /usr/bin/time -f \"$f 64:  %e s  %M KB\" janet64/bin/janet $f.janet > /dev/null  \n>   /usr/bin/time -f \"$f x32: %e s  %M KB\" janetx32/bin/janet $f.janet > /dev/null  \n> done  \n \nwords 64:  0.58 s  41904 KB  \nwords x32: 0.67 s  31856 KB  \nrecords 64:  6.40 s  138164 KB  \nrecords x32: 5.80 s  126916 KB  \ntree 64:  1.39 s  50504 KB  \ntree x32: 1.50 s  35532 KB  \nparse 64:  3.20 s  58504 KB  \nparse x32: 3.19 s  44428 KB\n\nwords 64:  0.63 s  41984 KB  \nwords x32: 0.70 s  31976 KB  \nrecords 64:  6.71 s  138240 KB  \nrecords x32: 5.77 s  126844 KB  \ntree 64:  1.40 s  50392 KB  \ntree x32: 1.48 s  35304 KB  \nparse 64:  3.37 s  58592 KB  \nparse x32: 3.09 s  44496 KB\n\nwords 64:  0.59 s  41756 KB  \nwords x32: 0.67 s  31788 KB  \nrecords 64:  6.50 s  138384 KB  \nrecords x32: 5.80 s  126960 KB  \ntree 64:  1.39 s  50288 KB  \ntree x32: 1.43 s  35560 KB  \nparse 64:  3.35 s  58520 KB  \nparse x32: 3.24 s  44572 KB\n\nwords 64:  0.60 s  42012 KB  \nwords x32: 0.67 s  31896 KB  \nrecords 64:  6.29 s  138448 KB  \nrecords x32: 6.00 s  126832 KB  \ntree 64:  1.38 s  50176 KB  \ntree x32: 1.43 s  35392 KB  \nparse 64:  3.36 s  58384 KB  \nparse x32: 3.13 s  44364 KB\n```\n\n### Conclusion\n\n`-mx32` cut RAM use by 21% (8-32%) with equal speed (-13% slower to 10% faster), while `-x32` reduced speed by half. Janet is a worst case where nanboxing already packs values into 8 bytes so the main benefit’s smaller headers. I invite others to test their software and languages similarly. With continued x32 support, we could use this as a default for scripts, utilities, daemons and the like. I thus believe Linux distros should include `-mx32` support and daemons and utilities should be compiled down for more efficient idling and day to day computing! It only costs a flag.\n\n* * *\n\n### P.S. Implications for Janet\n\nIf Janet works with smaller object headers, why not shrink them in the implementation for 64-bit use? By my understanding, Janet [heap objects](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L974) use 16 bytes to help the garbage collector:\n\n- 4 bytes for flags\n- 4 bytes of padding\n- 8 bytes linking to the next object\n\nReducing these would require a different garbage collection strategy e.g. our own allocator, which would hurt a core Janet use case: embedding in other projects.\n\nEach type then adds:\n\n- [string](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1081): 8 bytes for length and hash\n- [tuple](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1061): 8 bytes for length and hash, 8 bytes for source line and column info\n- [array](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1029): 8 bytes for count and capacity, 8 bytes for a pointer to the data\n- [struct](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1071): 12 bytes for length, hash and capacity, 4 bytes padding and 8 bytes for its prototype’s pointer\n- [table](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1045): 12 bytes for count, capacity and how many deleted, 4 bytes padding, 8 bytes for a pointer and 8 for the prototype’s pointer\n\nFor structs and tables in particular, we could regain 8 bytes through rearranging (not needing the later padding). Onlt tuples parsed from code need the source information (for errors); a flag could save normal tuples 8 bytes.\n\nUnfortunately, glibc’s `malloc` adds 8 bytes and rounds to multiples of 16 so structs would remain the same. But tables and (some) tuples would shrunk more than the above indicates!\n\n### Down the Rabbit Hole\n\nKernels must be compiled with `CONFIG_X86_X32_ABI` providing syscall entry points on Linux (with no Windows and Mac equivalent) which the compilers expose via `-mx32`.\n\nGood reading:\n\n- [https://lwn.net/Articles/1074897/#Comments](https://lwn.net/Articles/1074897/#Comments)\n- [https://blogsystem5.substack.com/p/x86-64-programming-models](https://blogsystem5.substack.com/p/x86-64-programming-models)\n\nQuestions:\n\n- can Zig via `zig cc -target x86_64-linux-muslx32` crosscompile for easy distribution?\n- how much performance benefit remains when using a faster allocator like mimalloc? The points will still be faster, at any rate.\n",
  "authors": [
    "alexalejandre.com by veqq"
  ],
  "captured_at": "2026-10-07T19:30:21.779631669+00:00",
  "category": "news",
  "content_html": "<hr />\n<blockquote>\n<p>It’s possible to save a dramatic amount of memory (close to half for programs with pointer heavy heaps) and also speed up programs by a modest amount (by way of more data fitting in cache) by using 32 bit pointers on 64 bit systems.</p>\n<p>The Linux x32 ABI lets you do just this, but it’s tragically underused and overlooked. It’s disabled by default on Debian (though you can enable it with a boot flag) and not even compiled in on Arch Linux. Most software compiles just fine for x32, but there isn’t much packaging for it so you do have to compile nearly everything yourself.</p>\n<p>I experimented with deploying mastodon on x32 and it cut the app’s memory usage from 650mb to 350mb. There’s so much potential here, but the work is mostly of the thankless coordination and communication type and I don’t have the time or motivation to push it forward myself. - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://lobste.rs/s/gns27z/what_are_your_programming_hunches_you#c_tw3vok\">Hailey</a></p>\n</blockquote>\n<h3>How to Compile for 32 Bits?</h3>\n<p>Janet libraries like Spork supply their own build flags, but we can hijack them with a fake <code>cc</code> which starts the real one with the necessary <code>-m32 -msse2 -mfpmath=sse</code> flags. I modified the beginning of my default <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://codeberg.org/veqq/install-latest-janet/src/branch/master/install-latest-janet.sh\">Janet build script</a>:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">!/bin/sh</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-set syntax-shell\">set</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>eu</span></span>\n\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">TARGET</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PWD</span></span>/janet32<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">JANET</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/bin/janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">mkdir</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>p</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-printf syntax-shell\">printf</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>#!/bin/sh\\nexec gcc -m32 -msse2 -mfpmath=sse &quot;$@&quot;\\n<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32/cc<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">chmod</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> +x <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32/cc<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-storage syntax-modifier syntax-shell\">export</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PATH</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32:<span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PATH</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-storage syntax-modifier syntax-shell\">export</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">JANET_TOOLCHAIN</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\">cc</span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-unset syntax-shell\">unset</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> JANET_PATH JANET_TREE</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">mkdir</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>p</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">rm</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>rf</span> build/spork janet</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://github.com/janet-lang/janet</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> janet</span>\n</span></span></code></pre>\n<p>Easy enough! Now let’s try it!</p>\n<h3>Failing on Arch</h3>\n<p>tl;dr: 20% memory reduction, 50% slower</p>\n<p>See the Scripts and Results</p>\n<p>This is on cachyos (arch, btw) with lib32-glibc lib32-gcc-libs. Adding this to a build script forces libraires like spork to build at 32 bit too!</p>\n<p>For <code>mem.janet</code>:</p>\n<pre><code class=\"language-janet\"><span class=\"code-snippet\" data-language=\"Janet\">(let [live @[]]\n  (for i 0 2_000_000\n    (array/push live [i (+ i 1)]))\n  (gccollect)\n  (print (length live)))\n</span></code></pre>\n<p>Note, these use Fish and I don’t want to rebuild my site with other language support:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">sudo</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> pacman<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>S</span> time <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> different from just time</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-command syntax-shell\">command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>v</span> ./bin/janet mem.janet <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> command skips the fish version</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-command syntax-shell\">command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>v</span> ./janet32/bin/janet mem.janet</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">2000000</span></span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> being timed: <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>./bin/janet mem.janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">User</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.24</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">System</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.05</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Percent</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> of CPU this job got: 100<span class=\"syntax-meta syntax-group syntax-expansion syntax-job syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-job syntax-shell\">%</span></span></span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Elapsed</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (wall clock</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (h:mm:ss or m:ss</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0:00.30</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> shared text size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unshared data size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> stack size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> total size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Maximum</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 145196</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Major</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (requiring I/O</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Minor</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (reclaiming a frame</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 33513</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Voluntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 1</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Involuntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 9</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">2000000</span></span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> being timed: <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>./janet32/bin/janet mem.janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">User</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.47</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">System</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.03</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Percent</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> of CPU this job got: 99<span class=\"syntax-meta syntax-group syntax-expansion syntax-job syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-job syntax-shell\">%</span></span></span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Elapsed</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (wall clock</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (h:mm:ss or m:ss</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0:00.50</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> shared text size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unshared data size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> stack size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> total size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Maximum</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 113716</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Major</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (requiring I/O</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 0</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Minor</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (reclaiming a frame</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 25686</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Voluntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 1</span>\n       <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Involuntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 21</span>\n</span></span></code></pre>\n<p>I added a 0 in the test</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-command syntax-shell\">command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>v</span> ./bin/janet mem.janet</span>\n                  <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-command syntax-shell\">command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>v</span> ./janet32/bin/janet mem.janet</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">20000000</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> being timed: <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>./bin/janet mem.janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">User</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 2.83</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">System</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.46</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Percent</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> of CPU this job got: 99<span class=\"syntax-meta syntax-group syntax-expansion syntax-job syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-job syntax-shell\">%</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Elapsed</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (wall clock</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (h:mm:ss or m:ss</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0:03.31</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> shared text size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unshared data size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> stack size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> total size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Maximum</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 1410668</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Major</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (requiring I/O</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Minor</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (reclaiming a frame</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 316820</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Voluntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 1</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Involuntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 164</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Exit</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> status: 0</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">20000000</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> being timed: <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>./janet32/bin/janet mem.janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">User</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 4.64</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">System</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.35</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Percent</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> of CPU this job got: 99<span class=\"syntax-meta syntax-group syntax-expansion syntax-job syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-job syntax-shell\">%</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Elapsed</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (wall clock</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (h:mm:ss or m:ss</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0:05.00</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> shared text size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unshared data size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> stack size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> total size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Maximum</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 1098372</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Major</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (requiring I/O</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Minor</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (reclaiming a frame</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 238633</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Voluntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 1</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Involuntary</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> context switches: 193</span>\n</span></span></code></pre>\n<p>For e.g. <code>declarative-dsls/tests.janet</code></p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">98</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> passed</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> being timed: <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>./bin/janet ./lib/janet/bin/judge declarative-dsls/tests.janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">User</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.42</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">System</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.02</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Percent</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> of CPU this job got: 100<span class=\"syntax-meta syntax-group syntax-expansion syntax-job syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-job syntax-shell\">%</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Elapsed</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (wall clock</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (h:mm:ss or m:ss</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0:00.45</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> shared text size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unshared data size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> stack size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> total size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Maximum</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 61900</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">declarative-dsls/tests.janet</span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">98</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> passed</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Command</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> being timed: <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>./bin/janet ./lib/janet/bin/judge declarative-dsls/tests.janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">User</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.70</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">System</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> time (seconds</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0.02</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Percent</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> of CPU this job got: 99<span class=\"syntax-meta syntax-group syntax-expansion syntax-job syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-job syntax-shell\">%</span></span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Elapsed</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (wall clock</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (h:mm:ss or m:ss</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0:00.72</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> shared text size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> unshared data size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> stack size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> total size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Maximum</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 54108</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Average</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> resident set size (kbytes</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Major</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (requiring I/O</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 0</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Minor</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> (reclaiming a frame</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">page</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> faults: 12735</span>\n</span></span></code></pre>\n<p>As Hailey said, Arch does not come with the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/X32_ABI\">x32 ABI</a> compiled, so I had to use <code>-m32</code> and while we do get a 20% memory savings, we execute 50% slower because half the registers aren’t used! <code>-m32</code> is the old 32-bit x86 mode using only 8 registers. To see the speed-up, we need to use <code>-mx32</code> which uses the 64-bit instruction set with shrunken 32-bit pointers. But I don’t want to recompile Linux…</p>\n<p>Unfortunately, Ubuntu also dropped x32 support.</p>\n<h3>Winning on Deprecated Ubuntu</h3>\n<p>Luckily, lazily, I have access to some deprecated servers (<em>of course</em> not in prod…) and OS installs, wasting hard disk space:</p>\n<blockquote>\n<p>Ubuntu 20.04 LTS Focal Fossa has reached its end of standard support on 31 May 2025.</p>\n</blockquote>\n<p>Ubuntu, so we have bash again:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">grep</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> X86_X32 /boot/config-<span class=\"syntax-meta syntax-group syntax-expansion syntax-command syntax-parens syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-parens syntax-begin syntax-shell\">(</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">uname</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>r</span></span><span class=\"syntax-punctuation syntax-section syntax-parens syntax-end syntax-shell\">)</span></span>  </span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">CONFIG_X86_X32</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\">y</span>\n</span></span></code></pre>\n<p>Just what we need, although <code>gcc version 9.4.0</code> is a bit old. We already have <code>build-essential git gcc-multilib libc6-dev-x32</code>. We are ready to soar! Here is our full <code>32janet.sh</code>:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">!/bin/bash</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-set syntax-shell\">set</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>eu</span></span>\n\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">TARGET</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PWD</span></span>/janetx32<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">JANET</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/bin/janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">mkdir</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>p</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> this forces Janet C libraries like Spork to build with 32bit also</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> FFI build test fails on -mx32 build so -DJANET_NO_FFI</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-printf syntax-shell\">printf</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>#!/bin/sh\\nexec gcc -mx32 -DJANET_NO_FFI &quot;$@&quot;\\n<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32/cc<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">chmod</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> +x <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32/cc<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-storage syntax-modifier syntax-shell\">export</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PATH</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/cc32:<span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PATH</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-storage syntax-modifier syntax-shell\">export</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">JANET_TOOLCHAIN</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\">cc</span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-unset syntax-shell\">unset</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> JANET_PATH JANET_TREE</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">mkdir</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>p</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://github.com/janet-lang/janet</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> janet</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-storage syntax-modifier syntax-shell\">export</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">CFLAGS</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>-fPIC -O3 -flto -fno-semantic-interposition -march=native<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span></span></span> <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> speed gains</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clean</span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> test</span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> install</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> ..</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>depth</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>1 https://github.com/janet-lang/spork build/spork</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>e</span> <span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>(if (bundle/installed? &quot;spork&quot;) (bundle/replace &quot;spork&quot; &quot;build/spork&quot;) (bundle/install &quot;build/spork&quot;))<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> ### Packages</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PM</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/lib/janet/bin/janet-pm<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://codeberg.org/veqq/declarative-dsls</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PM</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> install file::declarative-dsls <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> also does https://codeberg.org/veqq/varray</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://github.com/ianthehenry/judge <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> also does https://github.com/ianthehenry/cmd</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PM</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> install file::judge</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/lib/janet/bin/judge<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> declarative-dsls/tests.janet <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> to show that it worked</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span></span></span></code></pre>\n<p>And a `64janet.sh to compare it with:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">!/bin/bash</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-set syntax-shell\">set</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">-</span>eu</span></span>\n\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">TARGET</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PWD</span></span>/janet64<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">JANET</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/bin/janet<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-unset syntax-shell\">unset</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> JANET_PATH JANET_TREE</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">mkdir</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>p</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://github.com/janet-lang/janet</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> janet</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-storage syntax-modifier syntax-shell\">export</span> <span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">CFLAGS</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>-fPIC -O3 -flto -fno-semantic-interposition -march=native<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span></span></span> <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> speed gains</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clean</span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> test</span>\n<span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PREFIX</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span> <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">make</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> install</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> ..</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>depth</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>1 https://github.com/janet-lang/spork build/spork</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>e</span> <span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>(if (bundle/installed? &quot;spork&quot;) (bundle/replace &quot;spork&quot; &quot;build/spork&quot;) (bundle/install &quot;build/spork&quot;))<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> ### Packages</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-assignment syntax-shell\">PM</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-shell\">=</span><span class=\"syntax-string syntax-unquoted syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/lib/janet/bin/janet-pm<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://codeberg.org/veqq/declarative-dsls</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PM</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> install file::declarative-dsls <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> also does https://codeberg.org/veqq/varray</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://github.com/ianthehenry/judge <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> also does https://github.com/ianthehenry/cmd</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\"><span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">PM</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> install file::judge</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">JANET</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">TARGET</span></span>/lib/janet/bin/judge<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> declarative-dsls/tests.janet <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> to show that it worked</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span></span></span></code></pre>\n<p>Now we compare them:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">sudo</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> apt install time <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> different from just time</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">/usr/bin/time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>f</span> <span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>%e s  %M KB<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span> janet64/bin/janet janet64/lib/janet/bin/judge janet64/declarative-dsls/tests.janet</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">/usr/bin/time</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>f</span> <span class=\"syntax-string syntax-quoted syntax-single syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&#39;</span>%e s  %M KB<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&#39;</span></span> janetx32/bin/janet janetx32/lib/janet/bin/judge janetx32/declarative-dsls/tests.janet</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">2.42</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> s  61668 KB <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 64bit</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">2.36</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> s  53472 KB <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 32bit</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span></span></span></code></pre>\n<p>But <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://codeberg.org/veqq/declarative-dsls\">declarative-dsls</a> is a worst case scenario, using <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://codeberg.org/veqq/varray\">typed c arrays</a> for big speed ups, which don’t benefit much from this. Lets make some minimal benchmarks to really test the differences:</p>\n<p>See the Benchmarks Scripts</p>\n<p><code>words.janet</code> builds a text, splits it into words, counts them and sorts on that:</p>\n<pre><code class=\"language-janet\"><span class=\"code-snippet\" data-language=\"Janet\">(let [start (os/clock :monotonic)\n      rng (math/rng 42)\n      vocab (seq [i :range [0 5000]] (string &quot;w&quot; (math/rng-int rng 100000)))\n      text @&quot;&quot;\n      counts @{}]\n  (repeat 600000 (buffer/push text (in vocab (math/rng-int rng 5000)) &quot; &quot;))\n  (each word (string/split &quot; &quot; text)\n    (put counts word (+ 1 (get counts word 0))))\n  (pp (take 3 (sort-by |(- (in $ 1)) (pairs counts))))\n  (print (length counts) &quot; distinct words&quot;)\n  (print (- (os/clock :monotonic) start) &quot; s&quot;))\n</span></code></pre>\n<p><code>records.janet</code> groups structs by department and summarizes those departments, with unused extra fields like real code:</p>\n<pre><code class=\"language-janet\"><span class=\"code-snippet\" data-language=\"Janet\">(let [start (os/clock :monotonic)\n      rng (math/rng 7)\n      depts [:eng :ops :sales :legal :support]\n      people (seq [i :range [0 300000]]\n               {:id i\n               # :name and :tags not used\n                :name (string &quot;person-&quot; i)\n                :dept (in depts (math/rng-int rng 5))\n                :salary (+ 30000 (math/rng-int rng 90000))\n                :tags [(math/rng-int rng 10) (math/rng-int rng 10)]})\n      by-dept (group-by |(in $ :dept) people)]\n  (each dept (sorted (keys by-dept))\n    (let [staff (in by-dept dept)\n          salaries (map |(in $ :salary) staff)]\n      (pp [dept\n           (length staff)\n           (math/round (/ (sum salaries) (length staff)))\n           (length (filter |(&gt; $ 100000) salaries))])))\n  (print (- (os/clock :monotonic) start) &quot; s&quot;))\n</span></code></pre>\n<p><code>parse.janet</code> parses lines with a PEG and totals them:</p>\n<pre><code class=\"language-janet\"><span class=\"code-snippet\" data-language=\"Janet\">(let [start (os/clock :monotonic)\n      rng (math/rng 3)\n      lines (seq [i :range [0 200000]]\n              (string i &quot;,&quot; (math/rng-int rng 1000) &quot;,item-&quot; (math/rng-int rng 500) &quot;,&quot; (/ (math/rng-int rng 10000) 100)))\n      row (peg/compile\n            ~{:num (number (some (set &quot;0123456789.&quot;)))\n              :txt (capture (some (if-not &quot;,&quot; 1)))\n              :main (* :num &quot;,&quot; :num &quot;,&quot; :txt &quot;,&quot; :num -1)})\n      rows (map |(peg/match row $) lines)\n      totals @{}]\n  (each [id qty item price] rows\n    (put totals item (+ (get totals item 0) (* qty price))))\n  (print (length rows) &quot; rows, &quot; (length totals) &quot; items, total &quot; (math/round (sum (values totals))))\n  (print (- (os/clock :monotonic) start) &quot; s&quot;))\n</span></code></pre>\n<p><code>tree.janet</code> builds and walks binary trees, our pointer-heaviest example:</p>\n<pre><code class=\"language-janet\"><span class=\"code-snippet\" data-language=\"Janet\">(let [start (os/clock :monotonic)\n      make (fn make [depth]\n             (if (= depth 0)\n               [nil nil]\n               [(make (- depth 1)) (make (- depth 1))]))\n      check (fn check [node]\n              (if (in node 0)\n                (+ 1 (check (in node 0)) (check (in node 1)))\n                1))\n      long-lived (make 19)]\n  (var total 0)\n  (repeat 40 (+= total (check (make 14))))\n  (print total &quot; &quot; (check long-lived))\n  (print (- (os/clock :monotonic) start) &quot; s&quot;))\n</span></code></pre>\n<p>We benchmark:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-keyword syntax-control syntax-for syntax-shell\">for</span><span class=\"syntax-meta syntax-group syntax-for syntax-shell\"> f <span class=\"syntax-keyword syntax-control syntax-in syntax-shell\">in</span> words records tree parse</span><span class=\"syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell\">;</span> <span class=\"syntax-keyword syntax-control syntax-do syntax-shell\">do</span>  \n<span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span>   /usr/bin/time<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>f</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">f</span></span> 64:  %e s  %M KB<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> janet64/bin/janet <span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">f</span></span>.janet <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span> /dev/null  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span>   /usr/bin/time<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>f</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">f</span></span> x32: %e s  %M KB<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span> janetx32/bin/janet <span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">f</span></span>.janet <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span> /dev/null  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell\">&gt;</span> done  </span>\n \n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  0.58 s  41904 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 0.67 s  31856 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  6.40 s  138164 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 5.80 s  126916 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  1.39 s  50504 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 1.50 s  35532 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  3.20 s  58504 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 3.19 s  44428 KB</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  0.63 s  41984 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 0.70 s  31976 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  6.71 s  138240 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 5.77 s  126844 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  1.40 s  50392 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 1.48 s  35304 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  3.37 s  58592 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 3.09 s  44496 KB</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  0.59 s  41756 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 0.67 s  31788 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  6.50 s  138384 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 5.80 s  126960 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  1.39 s  50288 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 1.43 s  35560 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  3.35 s  58520 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 3.24 s  44572 KB</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  0.60 s  42012 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">words</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 0.67 s  31896 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  6.29 s  138448 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">records</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 6.00 s  126832 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  1.38 s  50176 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">tree</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 1.43 s  35392 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> 64:  3.36 s  58384 KB  </span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">parse</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> x32: 3.13 s  44364 KB</span>\n</span></span></code></pre>\n<h3>Conclusion</h3>\n<p><code>-mx32</code> cut RAM use by 21% (8-32%) with equal speed (-13% slower to 10% faster), while <code>-x32</code> reduced speed by half. Janet is a worst case where nanboxing already packs values into 8 bytes so the main benefit’s smaller headers. I invite others to test their software and languages similarly. With continued x32 support, we could use this as a default for scripts, utilities, daemons and the like. I thus believe Linux distros should include <code>-mx32</code> support and daemons and utilities should be compiled down for more efficient idling and day to day computing! It only costs a flag.</p>\n<hr />\n<h3>P.S. Implications for Janet</h3>\n<p>If Janet works with smaller object headers, why not shrink them in the implementation for 64-bit use? By my understanding, Janet <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L974\">heap objects</a> use 16 bytes to help the garbage collector:</p>\n<ul>\n<li>4 bytes for flags</li>\n<li>4 bytes of padding</li>\n<li>8 bytes linking to the next object</li>\n</ul>\n<p>Reducing these would require a different garbage collection strategy e.g. our own allocator, which would hurt a core Janet use case: embedding in other projects.</p>\n<p>Each type then adds:</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1081\">string</a>: 8 bytes for length and hash</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1061\">tuple</a>: 8 bytes for length and hash, 8 bytes for source line and column info</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1029\">array</a>: 8 bytes for count and capacity, 8 bytes for a pointer to the data</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1071\">struct</a>: 12 bytes for length, hash and capacity, 4 bytes padding and 8 bytes for its prototype’s pointer</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1045\">table</a>: 12 bytes for count, capacity and how many deleted, 4 bytes padding, 8 bytes for a pointer and 8 for the prototype’s pointer</li>\n</ul>\n<p>For structs and tables in particular, we could regain 8 bytes through rearranging (not needing the later padding). Onlt tuples parsed from code need the source information (for errors); a flag could save normal tuples 8 bytes.</p>\n<p>Unfortunately, glibc’s <code>malloc</code> adds 8 bytes and rounds to multiples of 16 so structs would remain the same. But tables and (some) tuples would shrunk more than the above indicates!</p>\n<h3>Down the Rabbit Hole</h3>\n<p>Kernels must be compiled with <code>CONFIG_X86_X32_ABI</code> providing syscall entry points on Linux (with no Windows and Mac equivalent) which the compilers expose via <code>-mx32</code>.</p>\n<p>Good reading:</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://lwn.net/Articles/1074897/#Comments\">https://lwn.net/Articles/1074897/#Comments</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://blogsystem5.substack.com/p/x86-64-programming-models\">https://blogsystem5.substack.com/p/x86-64-programming-models</a></li>\n</ul>\n<p>Questions:</p>\n<ul>\n<li>can Zig via <code>zig cc -target x86_64-linux-muslx32</code> crosscompile for easy distribution?</li>\n<li>how much performance benefit remains when using a faster allocator like mimalloc? The points will still be faster, at any rate.</li>\n</ul>\n",
  "content_markdown": "* * *\n\n> It’s possible to save a dramatic amount of memory (close to half for programs with pointer heavy heaps) and also speed up programs by a modest amount (by way of more data fitting in cache) by using 32 bit pointers on 64 bit systems.\n>\n> The Linux x32 ABI lets you do just this, but it’s tragically underused and overlooked. It’s disabled by default on Debian (though you can enable it with a boot flag) and not even compiled in on Arch Linux. Most software compiles just fine for x32, but there isn’t much packaging for it so you do have to compile nearly everything yourself.\n>\n> I experimented with deploying mastodon on x32 and it cut the app’s memory usage from 650mb to 350mb. There’s so much potential here, but the work is mostly of the thankless coordination and communication type and I don’t have the time or motivation to push it forward myself. - [Hailey](https://lobste.rs/s/gns27z/what_are_your_programming_hunches_you#c_tw3vok)\n\n### How to Compile for 32 Bits?\n\nJanet libraries like Spork supply their own build flags, but we can hijack them with a fake `cc` which starts the real one with the necessary `-m32 -msse2 -mfpmath=sse` flags. I modified the beginning of my default [Janet build script](https://codeberg.org/veqq/install-latest-janet/src/branch/master/install-latest-janet.sh):\n\n```bash\n#!/bin/sh\nset -eu\n\nTARGET=\"$PWD/janet32\"\nJANET=\"$TARGET/bin/janet\"\n\nmkdir -p \"$TARGET/cc32\"\nprintf '#!/bin/sh\\nexec gcc -m32 -msse2 -mfpmath=sse \"$@\"\\n' > \"$TARGET/cc32/cc\"\nchmod +x \"$TARGET/cc32/cc\"\nexport PATH=\"$TARGET/cc32:$PATH\"\nexport JANET_TOOLCHAIN=cc\n\nunset JANET_PATH JANET_TREE\n\nmkdir -p \"$TARGET\"\ncd \"$TARGET\"\nrm -rf build/spork janet\n\ngit clone https://github.com/janet-lang/janet\ncd janet\n```\n\nEasy enough! Now let’s try it!\n\n### Failing on Arch\n\ntl;dr: 20% memory reduction, 50% slower\n\nSee the Scripts and Results\n\nThis is on cachyos (arch, btw) with lib32-glibc lib32-gcc-libs. Adding this to a build script forces libraires like spork to build at 32 bit too!\n\nFor `mem.janet`:\n\n```janet\n(let [live @[]]\n  (for i 0 2_000_000\n    (array/push live [i (+ i 1)]))\n  (gccollect)\n  (print (length live)))\n```\n\nNote, these use Fish and I don’t want to rebuild my site with other language support:\n\n```bash\nsudo pacman -S time # different from just time\ncommand time -v ./bin/janet mem.janet # command skips the fish version\ncommand time -v ./janet32/bin/janet mem.janet\n\n2000000\n       Command being timed: \"./bin/janet mem.janet\"\n       User time (seconds): 0.24\n       System time (seconds): 0.05\n       Percent of CPU this job got: 100%\n       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.30\n       Average shared text size (kbytes): 0\n       Average unshared data size (kbytes): 0\n       Average stack size (kbytes): 0\n       Average total size (kbytes): 0\n       Maximum resident set size (kbytes): 145196\n       Average resident set size (kbytes): 0\n       Major (requiring I/O) page faults: 0\n       Minor (reclaiming a frame) page faults: 33513\n       Voluntary context switches: 1\n       Involuntary context switches: 9\n\n2000000\n       Command being timed: \"./janet32/bin/janet mem.janet\"\n       User time (seconds): 0.47\n       System time (seconds): 0.03\n       Percent of CPU this job got: 99%\n       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.50\n       Average shared text size (kbytes): 0\n       Average unshared data size (kbytes): 0\n       Average stack size (kbytes): 0\n       Average total size (kbytes): 0\n       Maximum resident set size (kbytes): 113716\n       Average resident set size (kbytes): 0\n       Major (requiring I/O) page faults: 0\n       Minor (reclaiming a frame) page faults: 25686\n       Voluntary context switches: 1\n       Involuntary context switches: 21\n```\n\nI added a 0 in the test\n\n```bash\ncommand time -v ./bin/janet mem.janet\n                  command time -v ./janet32/bin/janet mem.janet\n20000000\n        Command being timed: \"./bin/janet mem.janet\"\n        User time (seconds): 2.83\n        System time (seconds): 0.46\n        Percent of CPU this job got: 99%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.31\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 1410668\n        Average resident set size (kbytes): 0\n        Major (requiring I/O) page faults: 0\n        Minor (reclaiming a frame) page faults: 316820\n        Voluntary context switches: 1\n        Involuntary context switches: 164\n        Exit status: 0\n20000000\n        Command being timed: \"./janet32/bin/janet mem.janet\"\n        User time (seconds): 4.64\n        System time (seconds): 0.35\n        Percent of CPU this job got: 99%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.00\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 1098372\n        Average resident set size (kbytes): 0\n        Major (requiring I/O) page faults: 0\n        Minor (reclaiming a frame) page faults: 238633\n        Voluntary context switches: 1\n        Involuntary context switches: 193\n```\n\nFor e.g. `declarative-dsls/tests.janet`\n\n```bash\n98 passed\n        Command being timed: \"./bin/janet ./lib/janet/bin/judge declarative-dsls/tests.janet\"\n        User time (seconds): 0.42\n        System time (seconds): 0.02\n        Percent of CPU this job got: 100%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.45\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 61900\ndeclarative-dsls/tests.janet\n\n98 passed\n        Command being timed: \"./bin/janet ./lib/janet/bin/judge declarative-dsls/tests.janet\"\n        User time (seconds): 0.70\n        System time (seconds): 0.02\n        Percent of CPU this job got: 99%\n        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.72\n        Average shared text size (kbytes): 0\n        Average unshared data size (kbytes): 0\n        Average stack size (kbytes): 0\n        Average total size (kbytes): 0\n        Maximum resident set size (kbytes): 54108\n        Average resident set size (kbytes): 0\n        Major (requiring I/O) page faults: 0\n        Minor (reclaiming a frame) page faults: 12735\n```\n\nAs Hailey said, Arch does not come with the [x32 ABI](https://en.wikipedia.org/wiki/X32_ABI) compiled, so I had to use `-m32` and while we do get a 20% memory savings, we execute 50% slower because half the registers aren’t used! `-m32` is the old 32-bit x86 mode using only 8 registers. To see the speed-up, we need to use `-mx32` which uses the 64-bit instruction set with shrunken 32-bit pointers. But I don’t want to recompile Linux…\n\nUnfortunately, Ubuntu also dropped x32 support.\n\n### Winning on Deprecated Ubuntu\n\nLuckily, lazily, I have access to some deprecated servers (*of course* not in prod…) and OS installs, wasting hard disk space:\n\n> Ubuntu 20.04 LTS Focal Fossa has reached its end of standard support on 31 May 2025.\n\nUbuntu, so we have bash again:\n\n```bash\ngrep X86_X32 /boot/config-$(uname -r)  \nCONFIG_X86_X32=y\n```\n\nJust what we need, although `gcc version 9.4.0` is a bit old. We already have `build-essential git gcc-multilib libc6-dev-x32`. We are ready to soar! Here is our full `32janet.sh`:\n\n```bash\n#!/bin/bash\nset -eu\n\nTARGET=\"$PWD/janetx32\"\nJANET=\"$TARGET/bin/janet\"\n\nmkdir -p \"$TARGET/cc32\"\n# this forces Janet C libraries like Spork to build with 32bit also\n# FFI build test fails on -mx32 build so -DJANET_NO_FFI\nprintf '#!/bin/sh\\nexec gcc -mx32 -DJANET_NO_FFI \"$@\"\\n' > \"$TARGET/cc32/cc\"\nchmod +x \"$TARGET/cc32/cc\"\nexport PATH=\"$TARGET/cc32:$PATH\"\nexport JANET_TOOLCHAIN=cc\n\nunset JANET_PATH JANET_TREE\nmkdir -p \"$TARGET\"\ncd \"$TARGET\"\n\ngit clone https://github.com/janet-lang/janet\ncd janet\n\nexport CFLAGS='-fPIC -O3 -flto -fno-semantic-interposition -march=native' # speed gains\nPREFIX=\"$TARGET\" make clean\nPREFIX=\"$TARGET\" make\nPREFIX=\"$TARGET\" make test\nPREFIX=\"$TARGET\" make install\n\ncd ..\ngit clone --depth=1 https://github.com/janet-lang/spork build/spork\n\"$JANET\" -e '(if (bundle/installed? \"spork\") (bundle/replace \"spork\" \"build/spork\") (bundle/install \"build/spork\"))'\n\n# ### Packages\nPM=\"$TARGET/lib/janet/bin/janet-pm\"\ngit clone https://codeberg.org/veqq/declarative-dsls\n\"$JANET\" \"$PM\" install file::declarative-dsls # also does https://codeberg.org/veqq/varray\ngit clone https://github.com/ianthehenry/judge # also does https://github.com/ianthehenry/cmd\n\"$JANET\" \"$PM\" install file::judge\n\ntime \"$JANET\" \"$TARGET/lib/janet/bin/judge\" declarative-dsls/tests.janet # to show that it worked\n```\n\nAnd a \\`64janet.sh to compare it with:\n\n```bash\n#!/bin/bash\nset -eu\n\nTARGET=\"$PWD/janet64\"\nJANET=\"$TARGET/bin/janet\"\nunset JANET_PATH JANET_TREE\nmkdir -p \"$TARGET\"\ncd \"$TARGET\"\n\ngit clone https://github.com/janet-lang/janet\ncd janet\n\nexport CFLAGS='-fPIC -O3 -flto -fno-semantic-interposition -march=native' # speed gains\nPREFIX=\"$TARGET\" make clean\nPREFIX=\"$TARGET\" make\nPREFIX=\"$TARGET\" make test\nPREFIX=\"$TARGET\" make install\n\ncd ..\ngit clone --depth=1 https://github.com/janet-lang/spork build/spork\n\"$JANET\" -e '(if (bundle/installed? \"spork\") (bundle/replace \"spork\" \"build/spork\") (bundle/install \"build/spork\"))'\n\n# ### Packages\nPM=\"$TARGET/lib/janet/bin/janet-pm\"\ngit clone https://codeberg.org/veqq/declarative-dsls\n\"$JANET\" \"$PM\" install file::declarative-dsls # also does https://codeberg.org/veqq/varray\ngit clone https://github.com/ianthehenry/judge # also does https://github.com/ianthehenry/cmd\n\"$JANET\" \"$PM\" install file::judge\n\ntime \"$JANET\" \"$TARGET/lib/janet/bin/judge\" declarative-dsls/tests.janet # to show that it worked\n```\n\nNow we compare them:\n\n```bash\nsudo apt install time # different from just time\n/usr/bin/time -f '%e s  %M KB' janet64/bin/janet janet64/lib/janet/bin/judge janet64/declarative-dsls/tests.janet\n/usr/bin/time -f '%e s  %M KB' janetx32/bin/janet janetx32/lib/janet/bin/judge janetx32/declarative-dsls/tests.janet\n\n2.42 s  61668 KB # 64bit\n2.36 s  53472 KB # 32bit\n```\n\nBut [declarative-dsls](https://codeberg.org/veqq/declarative-dsls) is a worst case scenario, using [typed c arrays](https://codeberg.org/veqq/varray) for big speed ups, which don’t benefit much from this. Lets make some minimal benchmarks to really test the differences:\n\nSee the Benchmarks Scripts\n\n`words.janet` builds a text, splits it into words, counts them and sorts on that:\n\n```janet\n(let [start (os/clock :monotonic)\n      rng (math/rng 42)\n      vocab (seq [i :range [0 5000]] (string \"w\" (math/rng-int rng 100000)))\n      text @\"\"\n      counts @{}]\n  (repeat 600000 (buffer/push text (in vocab (math/rng-int rng 5000)) \" \"))\n  (each word (string/split \" \" text)\n    (put counts word (+ 1 (get counts word 0))))\n  (pp (take 3 (sort-by |(- (in $ 1)) (pairs counts))))\n  (print (length counts) \" distinct words\")\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\n`records.janet` groups structs by department and summarizes those departments, with unused extra fields like real code:\n\n```janet\n(let [start (os/clock :monotonic)\n      rng (math/rng 7)\n      depts [:eng :ops :sales :legal :support]\n      people (seq [i :range [0 300000]]\n               {:id i\n               # :name and :tags not used\n                :name (string \"person-\" i)\n                :dept (in depts (math/rng-int rng 5))\n                :salary (+ 30000 (math/rng-int rng 90000))\n                :tags [(math/rng-int rng 10) (math/rng-int rng 10)]})\n      by-dept (group-by |(in $ :dept) people)]\n  (each dept (sorted (keys by-dept))\n    (let [staff (in by-dept dept)\n          salaries (map |(in $ :salary) staff)]\n      (pp [dept\n           (length staff)\n           (math/round (/ (sum salaries) (length staff)))\n           (length (filter |(> $ 100000) salaries))])))\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\n`parse.janet` parses lines with a PEG and totals them:\n\n```janet\n(let [start (os/clock :monotonic)\n      rng (math/rng 3)\n      lines (seq [i :range [0 200000]]\n              (string i \",\" (math/rng-int rng 1000) \",item-\" (math/rng-int rng 500) \",\" (/ (math/rng-int rng 10000) 100)))\n      row (peg/compile\n            ~{:num (number (some (set \"0123456789.\")))\n              :txt (capture (some (if-not \",\" 1)))\n              :main (* :num \",\" :num \",\" :txt \",\" :num -1)})\n      rows (map |(peg/match row $) lines)\n      totals @{}]\n  (each [id qty item price] rows\n    (put totals item (+ (get totals item 0) (* qty price))))\n  (print (length rows) \" rows, \" (length totals) \" items, total \" (math/round (sum (values totals))))\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\n`tree.janet` builds and walks binary trees, our pointer-heaviest example:\n\n```janet\n(let [start (os/clock :monotonic)\n      make (fn make [depth]\n             (if (= depth 0)\n               [nil nil]\n               [(make (- depth 1)) (make (- depth 1))]))\n      check (fn check [node]\n              (if (in node 0)\n                (+ 1 (check (in node 0)) (check (in node 1)))\n                1))\n      long-lived (make 19)]\n  (var total 0)\n  (repeat 40 (+= total (check (make 14))))\n  (print total \" \" (check long-lived))\n  (print (- (os/clock :monotonic) start) \" s\"))\n```\n\nWe benchmark:\n\n```bash\nfor f in words records tree parse; do  \n>   /usr/bin/time -f \"$f 64:  %e s  %M KB\" janet64/bin/janet $f.janet > /dev/null  \n>   /usr/bin/time -f \"$f x32: %e s  %M KB\" janetx32/bin/janet $f.janet > /dev/null  \n> done  \n \nwords 64:  0.58 s  41904 KB  \nwords x32: 0.67 s  31856 KB  \nrecords 64:  6.40 s  138164 KB  \nrecords x32: 5.80 s  126916 KB  \ntree 64:  1.39 s  50504 KB  \ntree x32: 1.50 s  35532 KB  \nparse 64:  3.20 s  58504 KB  \nparse x32: 3.19 s  44428 KB\n\nwords 64:  0.63 s  41984 KB  \nwords x32: 0.70 s  31976 KB  \nrecords 64:  6.71 s  138240 KB  \nrecords x32: 5.77 s  126844 KB  \ntree 64:  1.40 s  50392 KB  \ntree x32: 1.48 s  35304 KB  \nparse 64:  3.37 s  58592 KB  \nparse x32: 3.09 s  44496 KB\n\nwords 64:  0.59 s  41756 KB  \nwords x32: 0.67 s  31788 KB  \nrecords 64:  6.50 s  138384 KB  \nrecords x32: 5.80 s  126960 KB  \ntree 64:  1.39 s  50288 KB  \ntree x32: 1.43 s  35560 KB  \nparse 64:  3.35 s  58520 KB  \nparse x32: 3.24 s  44572 KB\n\nwords 64:  0.60 s  42012 KB  \nwords x32: 0.67 s  31896 KB  \nrecords 64:  6.29 s  138448 KB  \nrecords x32: 6.00 s  126832 KB  \ntree 64:  1.38 s  50176 KB  \ntree x32: 1.43 s  35392 KB  \nparse 64:  3.36 s  58384 KB  \nparse x32: 3.13 s  44364 KB\n```\n\n### Conclusion\n\n`-mx32` cut RAM use by 21% (8-32%) with equal speed (-13% slower to 10% faster), while `-x32` reduced speed by half. Janet is a worst case where nanboxing already packs values into 8 bytes so the main benefit’s smaller headers. I invite others to test their software and languages similarly. With continued x32 support, we could use this as a default for scripts, utilities, daemons and the like. I thus believe Linux distros should include `-mx32` support and daemons and utilities should be compiled down for more efficient idling and day to day computing! It only costs a flag.\n\n* * *\n\n### P.S. Implications for Janet\n\nIf Janet works with smaller object headers, why not shrink them in the implementation for 64-bit use? By my understanding, Janet [heap objects](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L974) use 16 bytes to help the garbage collector:\n\n- 4 bytes for flags\n- 4 bytes of padding\n- 8 bytes linking to the next object\n\nReducing these would require a different garbage collection strategy e.g. our own allocator, which would hurt a core Janet use case: embedding in other projects.\n\nEach type then adds:\n\n- [string](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1081): 8 bytes for length and hash\n- [tuple](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1061): 8 bytes for length and hash, 8 bytes for source line and column info\n- [array](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1029): 8 bytes for count and capacity, 8 bytes for a pointer to the data\n- [struct](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1071): 12 bytes for length, hash and capacity, 4 bytes padding and 8 bytes for its prototype’s pointer\n- [table](https://github.com/janet-lang/janet/blob/c495f11f15a29033b5f52d66f82f13a105f98123/src/include/janet.h#L1045): 12 bytes for count, capacity and how many deleted, 4 bytes padding, 8 bytes for a pointer and 8 for the prototype’s pointer\n\nFor structs and tables in particular, we could regain 8 bytes through rearranging (not needing the later padding). Onlt tuples parsed from code need the source information (for errors); a flag could save normal tuples 8 bytes.\n\nUnfortunately, glibc’s `malloc` adds 8 bytes and rounds to multiples of 16 so structs would remain the same. But tables and (some) tuples would shrunk more than the above indicates!\n\n### Down the Rabbit Hole\n\nKernels must be compiled with `CONFIG_X86_X32_ABI` providing syscall entry points on Linux (with no Windows and Mac equivalent) which the compilers expose via `-mx32`.\n\nGood reading:\n\n- [https://lwn.net/Articles/1074897/#Comments](https://lwn.net/Articles/1074897/#Comments)\n- [https://blogsystem5.substack.com/p/x86-64-programming-models](https://blogsystem5.substack.com/p/x86-64-programming-models)\n\nQuestions:\n\n- can Zig via `zig cc -target x86_64-linux-muslx32` crosscompile for easy distribution?\n- how much performance benefit remains when using a faster allocator like mimalloc? The points will still be faster, at any rate.\n",
  "dateCreated": "2026-10-07T19:30:21.779631669+00:00",
  "date_created": "2026-10-06T22:26:46+00:00",
  "date_modified": "2026-10-06T22:26:46+00:00",
  "date_published": "2026-10-06T22:26:46+00:00",
  "description": "Comments",
  "external_url": "https://alexalejandre.com/programming/lisp/janet-for-the-x32-abi/",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/lobste-rs/2026/10/2026-10-06-janet-on-x32-32-bit-pointers-64-bit-speed-25-less-ram.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/lobste-rs/2026/10/2026-10-06-janet-on-x32-32-bit-pointers-64-bit-speed-25-less-ram.md"
  },
  "id": "urn:aggr:item:331d3a3c1c05e6990fb41890e1999db89ade4c67",
  "isBasedOn": {
    "@id": "https://alexalejandre.com/programming/lisp/janet-for-the-x32-abi/"
  },
  "mainEntity": {
    "@id": "https://alexalejandre.com/programming/lisp/janet-for-the-x32-abi/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/lobste-rs/2026-10-06-janet-on-x32-32-bit-pointers-64-bit-speed-25-less-ram/#webpage"
    },
    "author": [
      {
        "@type": "Person",
        "name": "alexalejandre.com by veqq"
      }
    ],
    "dateModified": "2026-10-06T22:26:46+00:00",
    "datePublished": "2026-10-06T22:26:46+00:00",
    "headline": "Janet on x32: 32-bit Pointers, 64-bit Speed, 25% Less RAM",
    "timeRequired": "PT12M",
    "url": "https://alexalejandre.com/programming/lisp/janet-for-the-x32-abi/",
    "wordCount": 2531
  },
  "name": "Archived snapshot: Janet on x32: 32-bit Pointers, 64-bit Speed, 25% Less RAM",
  "preview": null,
  "reading_minutes": 12,
  "replicated_at": null,
  "source": "lobste-rs",
  "source_name": "Lobsters: Top Stories of the Past Week",
  "summary": "Comments",
  "tags": [
    "linux",
    "performance"
  ],
  "temporalCoverage": "2026-10-07T19:30:21.779631669+00:00",
  "title": "Janet on x32: 32-bit Pointers, 64-bit Speed, 25% Less RAM",
  "url": "https://aggr.aymericbeaumet.com/items/lobste-rs/2026-10-06-janet-on-x32-32-bit-pointers-64-bit-speed-25-less-ram/",
  "word_count": 2531
}