One of the major performance issues with Menai has been that every value has been a heap allocation. Today I "unboxed" a few things!
Unboxing
In unboxing we're now using the lower 3 bits of a register value that were previously all zeros because these were pointers to heap-allocated objects. Now we use those 3 bits as a tag, and for small values we can store them directly in the register slot.
In this instance, none, boolean, and up to 61-bit integers are now stored directly in the register. This saves a huge amount of heap allocation and needless reference counting.
Performance numbers
BASE64-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
standard-1k 0.200 0.145
standard-64k 10.613 10.488
url-1k 0.146 0.144
url-64k 10.567 10.465
──────────────────────────────────────────────────────
BASE64-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
standard-1k 0.060 0.055
standard-64k 4.265 4.156
unpadded-1k 0.058 0.054
url-64k 4.306 4.215
──────────────────────────────────────────────────────
BMP-DECODE
────────────────────────────────────────────────────────
Case mean (ms) min (ms)
────────────────────────────────────────────────────────
truecolour-64x64 0.286 0.260
truecolour-128x128 1.196 1.183
truecolour-topdown-128x128 1.197 1.176
truecolour-alpha-128x128 1.489 1.469
padded-65x64 0.292 0.272
────────────────────────────────────────────────────────
BMP-ENCODE
────────────────────────────────────────────────────────
Case mean (ms) min (ms)
────────────────────────────────────────────────────────
truecolour-64x64 0.741 0.716
truecolour-128x128 7.149 7.115
truecolour-topdown-128x128 7.102 7.066
truecolour-alpha-128x128 9.864 9.692
padded-65x64 0.780 0.776
────────────────────────────────────────────────────────
CALENDAR
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
short_5d 0.023 0.018
month_20d 0.074 0.071
quarter_60d 0.219 0.217
year_250d 0.892 0.887
months_600d 1.552 1.508
──────────────────────────────────────────────────────
CSV-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
plain-1000x10 4.674 4.589
quoted-1000x10 6.916 6.835
escaped-1000x10 8.259 8.200
multiline-1000 1.488 1.414
wide-100x100 3.152 3.032
──────────────────────────────────────────────────────
CSV-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
plain-1000x10 5.034 4.878
quoted-1000x10 11.228 11.148
escaped-1000x10 7.100 7.080
wide-100x100 2.336 2.305
──────────────────────────────────────────────────────
DEFLATE-COMPRESS
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
text-4k 0.781 0.753
text-32k 3.229 3.096
incremental-16k 4.955 4.868
runs-32k 9.933 9.739
──────────────────────────────────────────────────────
DEFLATE-DECOMPRESS
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
text-4k 0.301 0.290
text-32k 0.475 0.464
incremental-16k 0.651 0.640
stored-8k 0.187 0.183
runs-32k 1.544 1.499
──────────────────────────────────────────────────────
DOCX-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
minimal 0.476 0.459
document-100 2.079 2.039
document-500 8.626 8.532
document-2000 33.542 33.332
styles-100 2.986 2.918
numbering-9 1.645 1.608
media-16 4.279 4.229
full-500 12.646 12.409
──────────────────────────────────────────────────────
DOCX-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
minimal 0.073 0.063
document-100 0.245 0.236
document-500 0.981 0.968
styles-100 0.379 0.372
numbering-9 0.128 0.121
media-16 0.275 0.264
full-500 1.238 1.227
──────────────────────────────────────────────────────
HTML-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
wide-1000 4.866 4.840
deep-200 0.427 0.422
attributes-500 3.685 3.661
mixed-500 3.898 3.874
entities-2000 11.500 11.461
void-1000 11.000 10.886
omitted-end-tags-1000 2.442 2.422
raw-text-500 4.458 4.438
realistic-500 7.968 7.905
──────────────────────────────────────────────────────
HTML-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
wide-1000 1.739 1.678
deep-200 0.208 0.164
attributes-500 0.809 0.798
mixed-500 1.939 1.932
void-1000 3.688 3.652
escaping-2000 4.078 4.038
declarations-1000 0.536 0.527
──────────────────────────────────────────────────────
JSON-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
object 0.012 0.010
flat_array 0.071 0.070
flat_object 0.062 0.061
mixed_nested 0.138 0.136
string_heavy 0.052 0.051
numbers_array 0.015 0.014
unicode_strings 0.008 0.007
long_string 0.061 0.060
deep_array 0.123 0.121
──────────────────────────────────────────────────────
JSON-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
object 0.012 0.009
flat_array 0.013 0.012
flat_object 0.028 0.027
mixed_nested 0.055 0.053
string_heavy 0.075 0.074
numbers_array 0.009 0.007
unicode_strings 0.003 0.002
long_string 0.248 0.245
──────────────────────────────────────────────────────
PNG-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
greyscale-64x64 1.905 1.888
greyscale-alpha-64x64 7.206 7.150
palette-128x128 5.272 5.242
truecolour-128x128 39.893 39.745
truecolour-alpha-128x128 53.443 53.097
truecolour-192x192 91.801 91.381
──────────────────────────────────────────────────────
PNG-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
truecolour-48x48 18.263 18.241
truecolour-96x96 161.738 161.594
truecolour-alpha-96x96 279.464 278.855
──────────────────────────────────────────────────────
PPTX-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
minimal 0.951 0.930
slides-10 3.743 3.718
slides-50 15.955 15.882
slides-200 62.064 61.754
shapes-50 12.202 12.151
masters-8 7.749 7.718
media-16 7.544 7.455
theme-and-masters 5.919 5.884
full-50 73.211 72.881
──────────────────────────────────────────────────────
PPTX-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
minimal 0.103 0.093
slides-10 0.314 0.304
slides-50 1.270 1.261
shapes-50 1.238 1.218
masters-8 0.639 0.630
media-16 0.507 0.497
theme-and-masters 0.485 0.476
full-50 5.896 5.754
──────────────────────────────────────────────────────
REGEXP
───────────────────────────────────────────────────────
Case mean (ms) min (ms)
───────────────────────────────────────────────────────
compile-per-line 1.444 1.408
search-prefix-log 0.031 0.030
search-class-numbers 0.034 0.032
search-alternation 0.077 0.075
search-all-class 9.981 9.961
search-all-prefix 1.507 1.492
search-groups-log 0.053 0.050
search-all-groups-numbers 34.673 34.534
split-whitespace 12.014 11.981
replace-whitespace 70.879 70.230
replace-groups-dates 24.444 24.340
chained-per-line 1.437 1.391
───────────────────────────────────────────────────────
RUBIKS_LIST
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
1-move 0.061 0.056
2-move 0.063 0.058
3-move 0.135 0.129
4-move 1.379 1.364
5-move 4.602 4.588
6-move 29.466 29.443
7-move 65.552 65.492
──────────────────────────────────────────────────────
RUBIKS_VECTOR
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
1-move 0.052 0.048
2-move 0.052 0.048
3-move 0.115 0.112
4-move 1.163 1.157
5-move 3.920 3.907
6-move 25.175 25.128
7-move 56.765 56.666
──────────────────────────────────────────────────────
SORT
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
n=10 0.005 0.003
n=50 0.029 0.027
n=100 0.064 0.063
n=250 0.188 0.187
n=500 0.424 0.423
n=1000 0.940 0.934
n=2500 2.769 2.754
n=5000 5.974 5.943
n=10000 13.008 12.978
──────────────────────────────────────────────────────
STATS
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
vector-mean-n=100 0.012 0.010
vector-mean-n=500 0.054 0.050
vector-mean-n=1000 0.098 0.097
vector-mean-n=2500 0.265 0.261
vector-mean-n=5000 0.562 0.556
vector-mean-n=10000 1.142 1.121
vector-mean-n=25000 2.932 2.899
vector-summary-n=100 0.078 0.076
vector-summary-n=500 0.485 0.483
vector-summary-n=1000 1.095 1.084
vector-summary-n=2500 3.143 3.135
vector-summary-n=5000 6.762 6.733
vector-summary-n=10000 14.595 14.536
vector-summary-n=25000 40.376 40.049
list-mean-n=100 0.011 0.010
list-mean-n=500 0.050 0.049
list-mean-n=1000 0.100 0.098
list-mean-n=2500 0.281 0.277
list-mean-n=5000 0.613 0.606
list-mean-n=10000 1.183 1.171
list-mean-n=25000 2.951 2.936
list-summary-n=100 0.078 0.076
list-summary-n=500 0.484 0.481
list-summary-n=1000 1.079 1.070
list-summary-n=2500 3.088 3.073
list-summary-n=5000 6.831 6.785
list-summary-n=10000 14.850 14.705
list-summary-n=25000 40.865 40.738
──────────────────────────────────────────────────────
STRING_OPS
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
search long/absent 0.019 0.016
search long/present 0.022 0.020
search short needle 0.023 0.020
search needle=haystack 0.184 0.180
hash 2000x8 0.036 0.034
hash 2000x64 0.096 0.095
hash 500x512 0.199 0.198
──────────────────────────────────────────────────────
SUDOKU_LIST
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
Easy (36 givens) 15.114 15.071
Medium (30 givens) 0.220 0.216
Hard (25 givens) 3207.785 3207.785
Expert (23 givens) 183.747 183.747
──────────────────────────────────────────────────────
SUDOKU_VECTOR
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
Easy (36 givens) 11.012 10.965
Medium (30 givens) 0.160 0.156
Hard (25 givens) 2417.269 2417.269
Expert (23 givens) 137.213 137.213
──────────────────────────────────────────────────────
XML-DECODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
wide-1000 2.323 2.300
deep-200 0.215 0.211
attributes-500 1.724 1.707
mixed-500 2.758 2.737
entities-2000 6.403 6.384
ooxml-500 5.945 5.920
──────────────────────────────────────────────────────
XML-ENCODE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
wide-1000 0.796 0.771
deep-200 0.130 0.116
attributes-500 0.750 0.741
mixed-500 1.927 1.918
escaping-2000 3.988 3.974
──────────────────────────────────────────────────────
ZIP-CREATE
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
single-deflate 0.517 0.489
single-stored 0.028 0.020
mixed-16 3.643 3.616
many-128 51.300 51.223
large-256k 23.639 23.304
──────────────────────────────────────────────────────
ZIP-ENTRIES
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
single-deflate 0.004 0.001
single-stored 0.002 0.001
mixed-16 0.013 0.011
many-128 0.086 0.080
large-256k 0.002 0.001
──────────────────────────────────────────────────────
ZIP-EXTRACT
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
single-deflate 0.233 0.224
single-stored 0.190 0.183
mixed-16 0.532 0.524
many-128 4.856 4.837
large-256k 2.218 2.201
──────────────────────────────────────────────────────
ZLIB-COMPRESS
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
text-4k 0.914 0.889
text-32k 4.443 4.395
incremental-16k 5.580 5.520
runs-32k 11.314 11.158
──────────────────────────────────────────────────────
ZLIB-DECOMPRESS
──────────────────────────────────────────────────────
Case mean (ms) min (ms)
──────────────────────────────────────────────────────
text-4k 0.440 0.428
text-32k 1.572 1.557
incremental-16k 1.198 1.188
runs-32k 2.610 2.579
──────────────────────────────────────────────────────Comparisons with the results from 2026-10-25
| Suite | Cases | Mean Δ% | Old total | New total |
|---|---|---|---|---|
| ZLIB-DECOMPRESS | 4 | −17.3 | 7.082 | 5.820 |
| ZIP-ENTRIES | 5 | −15.7 | 0.114 | 0.107 |
| BASE64-ENCODE | 4 | −13.8 | 10.148 | 8.689 |
| ZLIB-COMPRESS | 4 | −12.5 | 25.409 | 22.251 |
| DEFLATE-COMPRESS | 4 | −10.7 | 21.236 | 18.898 |
| PNG-DECODE | 6 | −9.5 | 227.123 | 199.520 |
| RUBIKS_LIST | 7 | −9.3 | 112.153 | 101.258 |
| BMP-DECODE | 5 | −8.4 | 4.895 | 4.460 |
| CSV-DECODE | 5 | −8.5 | 27.153 | 24.489 |
| ZIP-CREATE | 5 | −7.8 | 91.565 | 79.127 |
| PPTX-DECODE | 9 | −7.3 | 203.317 | 189.338 |
| DOCX-DECODE | 8 | −6.9 | 71.645 | 66.279 |
| HTML-DECODE | 9 | −6.6 | 54.062 | 50.244 |
| XML-DECODE | 6 | −6.0 | 20.629 | 19.368 |
| DEFLATE-DECOMPRESS | 5 | −5.9 | 3.362 | 3.158 |
| SORT | 9 | −5.8 | 25.150 | 23.401 |
| BMP-ENCODE | 5 | −5.8 | 27.193 | 25.636 |
| REGEXP | 12 | −5.3 | 166.990 | 156.574 |
| ZIP-EXTRACT | 5 | −5.1 | 8.595 | 8.029 |
| JSON-DECODE | 9 | −4.9 | 0.579 | 0.542 |
| STATS | 28 | −2.6 | 152.480 | 144.063 |
| PNG-ENCODE | 3 | −2.2 | 468.633 | 459.465 |
| RUBIKS_VECTOR | 7 | −1.7 | 89.159 | 87.242 |
| BASE64-DECODE | 4 | −1.6 | 23.653 | 21.526 |
| CSV-ENCODE | 4 | −1.3 | 25.939 | 25.698 |
| XML-ENCODE | 5 | −1.1 | 7.630 | 7.591 |
| DOCX-ENCODE | 7 | −1.0 | 3.357 | 3.319 |
| PPTX-ENCODE | 8 | −0.9 | 10.556 | 10.452 |
| SUDOKU_LIST | 4 | +0.2 | 3395.276 | 3406.866 |
| JSON-ENCODE | 8 | +0.5 | 0.426 | 0.443 |
| HTML-ENCODE | 7 | +0.5 | 12.919 | 12.997 |
| STRING_OPS | 7 | +2.1 | 0.578 | 0.579 |
| CALENDAR | 5 | +2.1 | 2.699 | 2.760 |
| SUDOKU_VECTOR | 4 | +4.7 | 2423.135 | 2565.654 |