SYNX 3.8: быстрее везде, и все парсеры наконец отвечают одинаково
SYNX 3.8.0 вообще не трогает язык. Изменилось другое: как быстро его читает каждая реализация, в TypeScript до 9,6 раза быстрее, в Rust в 2–3,6 раза, и то, что теперь на один и тот же файл все они дают один и тот же ответ.
by APERTURESyndicate · 17 октября 2026 г.
Вышел SYNX 3.8.0, и если вы просто пишете конфиги, в самих файлах ничего нового не увидите: грамматика не сдвинулась ни на миллиметр. Сдвинулось всё, что под ней. Ядро на Rust, пакет на TypeScript, биндинги для Python и Node и все семь нативных портов мы прогнали против 3.7.4 на одной машине и одном наборе файлов, а потом пересобрали там, где на самом деле уходило время.
Насколько быстрее
Коротко, прямо в самом формате:
# 3.7.4 -> 3.8.0, same machine, same files
rust
config_2_5kb 38.6us -> 17.6us
static_4mb 60.1ms -> 35.3ms
active_1_2mb 81.0ms -> 22.5ms
typescript_node
config_2_5kb 34.0us -> 20.4us
active_1_2mb 297.5ms -> 31.1ms
python
config_2_5kb 50.3us -> 17.6us
synxl_100k 173.7ms -> 83.2msСамый большой скачок у TypeScript на больших документах с маркерами, и причина там, честно говоря, немного неловкая: каждый ключ с :calc заново прогонял своё выражение по всем остальным ключам документа, так что работа росла с квадратом размера файла. В Rust основной выигрыш дала память. С системным аллокатором Windows обычный разбор почти половину времени просто просил память, а 3.8.0 просит её примерно в три раза реже на статических файлах и в пять раз реже в активном режиме. Двоичный .synxb получил то же самое: самые частые строки документа теперь получают самые короткие индексы, поэтому файлы стали меньше на 3–20 процентов в Rust и до 40 процентов в TypeScript, а один и тот же документ теперь всегда компилируется в одни и те же байты, чего 3.7.4 не обещал.
Парсеры, как выяснилось, не соглашались
Эту часть мы не искали. Чтобы убедиться, что быстрый код даёт те же результаты, мы стали скармливать одни и те же случайно сгенерированные документы ядру на Rust и пакету на TypeScript и сравнивать, что выходит, и 17 процентов документов с !active вышли разными. Где-то ошибался TypeScript, где-то Rust, а где-то Rust ошибался каждый раз по-новому: он обходил объекты в порядке хеш-таблицы, так что пример tax:calc / total:calc прямо из спецификации примерно в половине запусков падал с CALC_ERR.
А стоило начать искать, как находилось ещё. Маркеры внутри элементов списка в Rust не применялись вообще. Synx.stringify и .synxb меняли данные на обратном пути: "007" возвращалось числом 7, блоки кода |+ теряли отступы, и 1 777 случайных документов из 3 000 не переживали запись и чтение. Некоторые документы могли даже уронить весь процесс: от :clamp:nan:5 Rust паниковал, а файл, подключающий сам себя, переполнял стек. Все 55 таких дефектов исправлены, и на финальном коде ядро на Rust и TypeScript совпадают на всех 70 000 сгенерированных документах.
Семь портов, и все на 3.8.0
У SYNX есть ещё нативные парсеры для Go, Java, .NET, Dart, C++, Swift и Godot, и они отстали на несколько релизов. Теперь все они на 3.8.0 и проверены тем же способом, против ядра на Rust, на тысячах сгенерированных документов каждый, и расхождений не осталось. Одни изменились куда сильнее других: порты на C++ и Swift тратили на активный документ в 1,2 МБ 88 и 47 секунд, а теперь 33 и 95 миллисекунд, а аддон для Godot до этого релиза под Godot 4.7 даже не компилировался.
Как обновиться
Ваши файлы .synx менять не нужно. Пакеты: @aperturesyndicate/synx-format в npm, synx-core на crates.io и synx-format в PyPI, а порты приходят через свои обычные реестры. Если вы используете synx-core из Rust напрямую, объекты теперь упорядоченный IndexMap, а не HashMap: коду, который сам строит HashMap и заворачивает его, понадобится .collect(), а всё, что читает через get и перебор, собирается как раньше.
Одно формат по-прежнему выразить не может: список внутри элемента списка, за которым идёт следующий элемент, не переживает запись и обратное чтение, потому что SYNX держит открытым только один список за раз. Это запланировано на 4.0 вместе с компактными строками, которые на лабораторной копии ядра ускорили разбор ещё в 1,2–1,5 раза.
Все изменения с цифрами есть в списке изменений и в релизе 3.8.0 на GitHub.



