M0 — JSON performance, Apple M4
Первое сравнение явной мутации со значениями A0/A3 на одной машине. Это измерение выбранного скалярного автомата, не гарантия скорости всех программ.
Компилятор M0: c5d5ec8e1dc8a664eee13530cba37d7de8252573; A0: b320611, A3: b210c9f.
Один набор из шести документов по ~256 КиБ, чанки 2048 байтов, O2,
десять перемешанных повторов на вариант/нагрузку, одинаковый C driver без LTO.
C++ by-value также измерен и сохранён в полном отчёте.
| Нагрузка, медиана МиБ/с | A0 | A3 | M0 | C++ in-place | Rust |
|---|---|---|---|---|---|
| ascii | 42.72 | 69.93 | 190.55 | 429.98 | 417.72 |
| unicode | 55.70 | 95.15 | 213.50 | 525.94 | 509.44 |
| escaped | 54.83 | 89.50 | 205.71 | 517.73 | 468.94 |
| numbers | 38.89 | 99.68 | 220.97 | 431.04 | 411.87 |
| long-string | 63.85 | 117.75 | 272.49 | 621.90 | 591.07 |
| depth64 | 29.55 | 48.82 | 170.30 | 305.00 | 284.56 |
M0 быстрее A3 в 2,22–3,49 раза, но C++ in-place и Rust остаются быстрее M0 примерно в 1,7–2,5 раза. Цель паритета пока не достигнута. Mutable JSON использует те же правила переходов; UTF-8 helper остаётся value-based. Это отдельный кандидат для дальнейшего исследования, а не установленная единственная причина разрыва.
В диагностическом, нетаймируемом исполнении оптимизированного LLVM IR на ASCII
bulk-copy составляют: A0 ~721, A3 ~256, M0 0 байтов на входной байт. Счётчики
охватывают memcpy/memmove; скалярные load/store и регистровые перемещения туда не
входят. Ноль bulk-copy не означает нулевой трафик памяти. Frame горячего
__liza_json_mut_step — 32 байта; у специализированного A3 — 720, у A0 — 4480.
Это размеры отдельных функций, не максимальная глубина стека программы.
Перед измерением все шесть реализаций согласованы с ожидаемыми результатами на 6785 partitioned cases и 861 CLI-проверке (включая исходный liza-json). Данные включают 360 сырых core samples, версии инструментов, целевую архитектуру, хеши корпуса и артефактов. CLI throughput здесь не измеряется.
Полный отчёт, IR, assembly и frame, манифест.
Воспроизведение: benchmarks/mutable/run.py --candidate <commit> --output <new-dir>.
Без измерений скорости используется --check-only. Исходный baseline и его
сохранённый отчёт не изменены. Сопоставлять новые результаты нужно с полным
повторным запуском на той же машине, а не с выбором самых быстрых образцов.