← На главную

Zig ускорил компиляцию до 250 мс и --help до 14 мс

25.06.2026 14:19 · hackernews

В Zig произошло сразу несколько крупных изменений. Мэттью Лагг переработал LLVM backend — раньше произвольные целочисленные типы вроде u40 напрямую транслировались в i40 из LLVM IR, а это плохо оптимизировалось и давало баги. Теперь такие типы в памяти приводятся к стандартным размерам (i16, i32), как это делает Clang для _BitInt(N). Но из-за этого сломался @bitCast — его старая семантика завязывалась на reinterpretation в памяти. Лагг переписал @bitCast: теперь он работает не с байтами в памяти, а с «логическими битами» типа. Результат не зависит от endianness — первый элемент массива всегда становится младшими битами. Это уже работало в x86_64 backend, а теперь и в LLVM, C и comptime. Ещё разрешили @bitCast для enum и запретили для векторов указателей. В итоге сам компилятор Zig стал работать на 5% быстрее.

Второй большой блок — новый ELF линкер, который дебютировал в 0.16.0, но был сырым. Сейчас он уже собирает сам компилятор Zig с LLVM и LLD, поддерживает внешние библиотеки и C-код. Главная фишка — быстрая инкрементальная сборка: на клоне Тетриса Эндрю Келли правки компилируются за 30 мс, а сам компилятор — за 250–300 мс вместо 36 секунд с нуля. Пока не хватает генерации DWARF-отладочной информации, но это в планах.

Эндрю Келли разделил процесс сборки zig build. Раньше build.zig и весь build runner компилировались в один тяжёлый процесс в Debug-режиме. Теперь build.zig (его называют configurer) выполняется отдельно, сериализует граф сборки в бинарный конфигурационный файл, а родительский процесс параллельно компилирует maker в Release-режиме. Результат — zig build --help вместо 150 мс выполняется за 14 мс. Изменения API: вместо прямого доступа к b.args теперь используется addPassthruArgs. Для тех, кто работает с пакетами: теперь зависимости хранятся локально в zig-pkg (рядом с build.zig), а глобальный кеш — сжатые архивы. Появился флаг --fork — можно временно заменить любой пакет в дереве зависимостей на локальный каталог с форком, прямо из командной строки. Это упрощает отладку и патчинг.

Наконец, улучшили type resolution: теперь компилятор лениво анализирует поля типов — если тип не инициализирован, на @compileError внутри него не ругается. Сообщения об ошибках dependency loop стали человекочитаемыми — показывают, какой тип на какой ссылается. Инкрементальная компиляция с LLVM backend тоже наконец работает и выдаёт ошибки за миллисекунды. А ещё std.Io.Evented (экспериментальные «зелёные потоки» на переключении стеков) теперь позволяет менять реализацию I/O без переписывания кода приложения — например, переключиться с Threaded на Evented (с io_uring). Пока есть просадка производительности, но концепция работает.

Читать оригинал →