Простые истории про ускорение сборки большой кодобазы

Мы часто читаем инструкции про настройку волшебных флагов компилятора для ускорения сборки проектов. Да, эти способы работают, но не всегда могут дать ту экономию времени, которой хочется. Реальной проблемой может быть большое количество кода. Иногда примитивное удаление старого неиспользуемого кода, распараллеливание сборки и разделение на компоненты дают более ощутимый результат.

eb46e8512e62780ad43988fa54183e16.png

Удаление неиспользуемого кода

У вас большая кодобаза? Если да, то скорее всего там есть неиспользуемый код. До какого-то момента я и не думала, что простое удаление кода может увеличить скорость сборки почти в три раза. В начале 2020 года нам передали на поддержку достаточно старый компонент, предоставляющий сервисы, библиотеки и приложения для работы с устройствами и платами. После того, как была выполнена настройка билда этого компонента в нашей инфраструктуре, заметили, что время билда достаточно большое — 35 минут. Мы уже  разрабатывали компоненты Core функциональности (предоставляющие фичи для других компонентов), и там общее время билда пяти компонентов составляло в сумме минут 30. А билд одного нового компонента занимал 35 минут. Мы понимали, что сборка предоставляемой функциональности не может занимать столько времени, поэтому решили выполнить инвентаризацию кода.

В компоненте встречались названия приложений с постфиксами v1/v2, NG (или New Generation), что явно указывало на дубликаты. Кажется, при создании нового приложения не удалялось старое.

В первую очередь в список кандидатов на удаление пошло все, чего не было в инсталляторе. Среди них были графические и консольные приложения. Теперь оставалось выяснить, пользуется ли этими приложениями кто-то внутри компании. То, чего не было в инсталляторе, точно не поставлялось конечному пользователю, но все ещё могло использоваться тестировщиками, программистами и системными инженерами на фабрике при компании, поскольку приложения поставлялись в сборка. 

 Также мы составили список всех библиотеки, которые есть в компоненте и проверили их использование во всей кодобазе (это было несложно сделать, так есть поиск по всему коду OpenGrok) .

Получение актуального перечня списка используемых приложений и библиотек заняло месяц. После этого мы с чистой совестью почистили наш репозиторий. И ура, время сборки составило всего 12 минут.

Распараллеливание сборок

Мы иногда слышим об этих инструментах, но, к сожалению, на практике они используются почему-то не так часто. Лично я встречала использование подобного инструмента, а именно Incredibuild, только один раз. Этот инструмент произвёл неизгладимое впечатление. Я только перешла в новый проект, выкачала репозиторий, билжу… Локальный билд занял 30 минут. Я в шоке, т.к. была наслышана про этот проект: используют крутые инструменты, генераторы кода задействованы для целых слоев кода, наличие мини-сервера основного продукта, позволяющего запускать полноценные смоки на компоненте, а не на конечной сборке продукта. Пошла я значит узнавать, как все работают с этим. Мне ответили, что используют Incredibuild. До этого момента я никогда не пользовалась распараллеливанием сборок, поэтому была приятно удивлена результатом: время полной сборки составило 5 минут (а было 30 минут). Единственная сложность этого подхода: правильная настройка зависимостей всех проектов. Здесь Incredibuild использовался только для локальных сборок. Интеграция в билд-систему была безуспешной, т.к. периодически ломались зависимости проектов, а иметь красный билд только по этой причине не хотелось.

Компонентная архитектура

Компоненты — что-то вроде конструктора. Процесс сборки компонент выполняется следующим образом. После сборки каждого компонента на сервер выкладываются запчасти, необходимые для использования этого компонента: это у нас бинари и, например, в случае c++ интерфейсы в h-файлах. Теперь нам не нужно каждый раз билдить этот код, а просто выкачиваем требуемую версию компонента. Далее запускаются билды следующих компонент, зависящих от предыдущего. Ещё хочется отметить, что тесты для компонента запускаются только если есть в нем изменения (изменился код самого компонента, обновилась версия используемых компонент более низкого уровня), что логично. При такой архитектуре можно сэкономить много времени, особенно на компонентах, которые редко или почти не меняются.

 Вот такие способы могут ускорить время сборки, и программисты будут довольны. 

© Habrahabr.ru