Сокращение времени компиляции Rust

Когда начинаешь работать с Rust первое что замечаешь - довольно большое время сборки, особенно если до Rust приходилось работать с Golang. Время сборки довольно большая тема, разработчики Rust уделяют ей особое внимание и предпринимают шаги к его сокращению. Но иногда можно самому ускорить сборку.

Убрать большие crate

Предположение заключается в том, что чем больше библиотека - тем больше времени нужно на ее компиляцию. Если исполняемый файл большой, а процент собственного кода незначительный - значит, возможно, мы используем большой crate, который в теории можно заменить. Чтобы быстро определить, что проблема может заключаться в этом - оценить размер готового исполняемого двоичного файла.

Это приводит нас к желанию выяснить, какие “ящики” непосредственно используются и как они влияют на нашу сборку с точки зрения размера.

Для подобной оценки есть инструмент cargo-bloat. Установить его можно следующим образом:

$ cargo install cargo-bloat

Хотя cargo-bloat имеет довольно много различных опций, мы воспользуемся только анализом используемых crate.

$ cargo bloat --release --crates

Вывод получился следующим:

 File  .text     Size Crate
20.5%  31.7%   1.3MiB spirv_cross
 9.2%  14.3% 608.5KiB wgpu
 8.8%  13.6% 579.8KiB std
 6.1%   9.4% 401.3KiB image
 3.3%   5.0% 215.5KiB wgpu_core
 3.1%   4.9% 208.0KiB gfx_backend_metal
 3.0%   4.6% 195.2KiB naga
 1.6%   2.5% 106.9KiB winit
 1.4%   2.2%  92.2KiB [Unknown]
 1.2%   1.9%  79.4KiB jpeg_decoder
 1.0%   1.5%  65.6KiB hashbrown
 0.5%   0.8%  35.4KiB spirv_headers
 0.5%   0.8%  34.8KiB scoped_threadpool
 0.5%   0.8%  34.6KiB png
 0.5%   0.8%  32.4KiB gfx_hal
 0.5%   0.7%  30.6KiB rayon_core
 0.4%   0.7%  29.1KiB metal
 0.4%   0.6%  24.8KiB tiff
 0.3%   0.4%  17.6KiB gfx_memory
 0.2%   0.3%  13.3KiB parking_lot
 1.9%   2.9% 124.8KiB And 34 more crates. Use -n N to show more.
64.6% 100.0%   4.2MiB .text section size, the file size is 6.5MiB

Согласно теории, spirv_cross может приводить к замедлению сборки, так как он единолично занимает 20% от исполняемого файла. Соответственно, зная это можно отказаться от подобных “больших” crate, конечно если есть альтернативы.

Использовать альтернативный компоновщик

Цель компоновщика создать окончательный результат компиляции из различных выходных данных компилятора. Виды и типы объектов компилятора различаются в зависимости от компилятора.

В Rust на некоторых платформах компоновка занимает значительное время от общего процесса сборки - хорошее место для оптимизации.

Говорить буду исключительно про macOS и nightly rust компилятор. Мы будем использовать zld, который не так давно стал доступен для macOS. Почему zld быстрее стандартного, можно почитать в readme того же репозитория.

Установка:

brew install michaeleisel/zld/zld

Далее в .cargo/config или локально для проекта прописать:

[target.x86_64-apple-darwin]
rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/zld", "-Zshare-generics=y"]

Для моего проекта время сборки уменьшилось, но не кардинально, но некоторые пользователи рассказывают о двух кратном ускорении.

Вывод

Конечно, есть еще множество способов сократить время сборки, это лишь парочка из них. Какой подойдет именно вам никто не скажет, нужно экспериментировать и проверять на бою.