Подтвердить что ты не робот

Какие стратегии вы использовали для улучшения времени сборки крупных проектов?

Я когда-то работал над проектом на С++, который занимал около полутора часов для полной перестройки. Малые циклы редактирования, сборки, тестирования занимали около 5-10 минут. Это был непроизвольный кошмар.

Какое худшее время, с которым когда-либо приходилось обращаться?

Какие стратегии вы использовали для улучшения времени сборки больших проектов?

Update:

Как вы думаете, насколько виноват в этом проблема используемый язык? Я думаю, что С++ подвержен массивным зависимостям от крупных проектов, что часто означает, что даже простые изменения исходного кода могут привести к массивной перестройке. На каком языке, по вашему мнению, лучше справляются с большими проблемами зависимости проекта?

4b9b3361

Ответ 1

  • Переслать декларацию
  • pimpl idiom
  • Предварительно скомпилированные заголовки
  • Параллельная компиляция (например, надстройка MPCL для Visual Studio).
  • Распределенная компиляция (например, Incredibuild для Visual Studio).
  • Инкрементная сборка
  • Разделить сборку в нескольких "проектах", чтобы не компилировать весь код, если он не нужен.

[Редактировать позже] 8. Покупайте более быстрые машины.

Ответ 2

Моя стратегия довольно проста - я не занимаюсь крупными проектами. Вся толпа современных вычислений находится вдали от гигантского и монолитного и к маленькому и сложному. Поэтому, когда я работаю над проектами, я разбиваю вещи на библиотеки и другие компоненты, которые могут быть построены и протестированы независимо и которые имеют минимальные зависимости друг от друга. "Полная сборка" в такой среде никогда не происходит, поэтому нет проблем.

Ответ 3

Один трюк, который иногда помогает, заключается в том, чтобы включить все в один .cpp файл. Поскольку вложения обрабатываются один раз в файл, это может сэкономить вам много времени. (Недостатком этого является то, что он не позволяет компилятору распараллелить компиляцию)

Вы должны указать, что несколько файлов .cpp должны быть скомпилированы параллельно (-j с make on linux,/MP на MSVC - MSVC также имеет возможность скомпилировать несколько проектов параллельно. Это отдельные параметры и нет причин, по которым вы не должны использовать оба)

В том же ключе распределенные сборки (например, Incredibuild) могут помочь снять нагрузку с одной системы.

SSD-диски должны быть большой победой, хотя я сам ее не тестировал (но сборка С++ затрагивает огромное количество файлов, что может быстро стать узким местом).

Предварительно скомпилированные заголовки могут также помочь при использовании с осторожностью. (Они также могут навредить вам, если их нужно перекомпилировать слишком часто).

И, наконец, важно минимизировать зависимости в самом коде. Используйте идиому pImpl, используйте форвардные объявления, сохраняйте код как можно более модульным. В некоторых случаях использование шаблонов может помочь вам разделить классы и минимизировать зависимости. (В других случаях шаблоны могут значительно замедлить компиляцию, конечно)

Но да, вы правы, это очень языковая вещь. Я не знаю другого языка, который страдает от этой проблемы. Большинство языков имеют модульную систему, которая позволяет им исключать файлы заголовков, в какой области огромный фактор. C имеет заголовочные файлы, но является таким простым языком, что время компиляции по-прежнему управляемо. С++ становится наихудшим из обоих миров. Большой сложный язык и ужасный примитивный механизм сборки, который требует большого количества кода для повторного анализа снова и снова.

Ответ 4

  • Многоядерная компиляция. Очень быстро с 8 ядрами, скомпилированными на I7.
  • Инкрементная привязка
  • Внешние константы
  • Удалены встроенные методы на классах С++.

Последние два дали нам сокращенное время соединения от 12 минут до 1-2 минут. Обратите внимание, что это необходимо только в том случае, если вещи имеют огромную видимость, то есть "повсюду", и если существует много разных констант и классов.

Приветствия

Ответ 6

Unity Builds

IncrediBuild

Указатель на реализацию

передовые декларации

компилирование "готовых" разделов proejct в dll

Ответ 7

Лучшее предложение - создать make файлы, которые действительно понимают зависимости и не будут автоматически перестраивать мир для небольшого изменения. Но если полная перестройка занимает 90 минут, а небольшая перестройка занимает 5-10 минут, шансы хорошие, что ваша система сборки уже делает это.

Может ли сборка выполняться параллельно? Либо с несколькими ядрами, либо с несколькими серверами?

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

Ограничьте сборку одним "потоком", если это применимо. "Полный продукт" может включать в себя такие вещи, как отладочная версия или как 32, так и 64-разрядные версии, или может включать файлы справки или справочные страницы, которые производятся/создаются каждый раз. Удаление компонентов, которые не являются необходимыми для разработки, может значительно сократить время сборки.

Содержит ли сборку также продукт? Это действительно необходимо для разработки и тестирования? Содержит ли сборка некоторые основные тесты на здравомыслие, которые можно пропустить?

Наконец, вы можете повторно разбить базу кода на более модульную и иметь меньше зависимостей. Масштаб С++ Software Design - отличная справочная информация для обучения разделить большие программные продукты на то, что легче поддерживать и быстрее создавать.

EDIT: построение локальной файловой системы в отличие от установленной файловой системы NFS также может значительно ускорить время сборки.

Ответ 8

ccache и distcc (для проектов C/С++) -

ccache кэширует скомпилированный вывод, используя предварительно обработанный файл в качестве "ключа" для поиска вывода. Это здорово, потому что предварительная обработка довольно быстро, и довольно часто изменения, которые перекомпилируют, на самом деле не меняют источник для многих файлов. Кроме того, он действительно ускоряет полную перекомпиляцию. Также приятным является экземпляр, в котором вы можете иметь общий кеш среди членов команды. Это означает, что только первый парень, который может захватить последний код, действительно компилирует что-либо.

distcc выполняет распределенную компиляцию по сети машин. Это полезно только в том случае, если у вас есть сеть машин для компиляции. Это хорошо сочетается с ccache и только перемещает предварительно обработанный источник, поэтому единственное, что вам нужно беспокоиться в системах движков компилятора, это то, что у них есть правильный компилятор (нет необходимости, чтобы заголовки или все исходное дерево были видимыми).

Ответ 9

  • Исправить флаги оптимизации компилятора,
  • использовать -j4 для gmake для параллельной компиляции (многоядерный или одноядерный)
  • Если вы используете clearmake, используйте winking
  • мы можем извлечь флаги отладки в крайних случаях.
  • Используйте несколько мощных серверов.

Ответ 11

  • Свернуть свой общедоступный API
  • Минимизировать встроенные функции в вашем API. (К сожалению, это также увеличивает требования к компоновщикам).
  • Развернуть форвардные объявления.
  • Уменьшение связи между кодом. Например, передайте два целых числа в функцию для координат вместо вашего собственного класса Point, у которого есть собственный файл заголовка.
  • Используйте Incredibuild. Но иногда у него есть некоторые проблемы.
  • НЕ помещайте код, который экспортируется из двух разных модулей в заголовочный файл SAME.
  • Используйте идиому PImple. Ранее упоминалось, но повторяется.
  • Используйте предварительно скомпилированные заголовки.
  • Избежать С++/CLI (т.е. управляемый С++). Налицо также влияние времени компоновщика.
  • Избегайте использования глобального файла заголовка, который включает в себя все остальное в вашем API.
  • Не устанавливайте зависимость от файла lib, если ваш код действительно не нужен.
  • Знайте разницу между включением файлов с кавычками и угловыми скобками.

Ответ 12

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

Эффективность и правильность важнее скорости компиляции.

Ответ 13

В Visual Studio вы можете одновременно настроить количество проектов. Его значение по умолчанию равно 2, что увеличивает время.

Это поможет, если вы не хотите связываться с кодом.

Ответ 14

Это список вещей, которые мы сделали для разработки под Linux:

  • Как заметил Воин, используйте параллельные сборки (make -jN)
  • Мы используем распределенные сборки (в настоящее время icecream, которые очень легко настроить), с этим мы можем иметь десятки или процессоры на данное время. Это также имеет преимущество, заключающееся в том, чтобы создавать сборки на самых мощных и менее загруженных машинах.
  • Мы используем ccache, чтобы при чистке вам не нужно было перекомпилировать ваши источники, которые не менялись, они копировались из кеша.
  • Отметим также, что отладочные сборки обычно быстрее компилируются, поскольку компилятор не нуждается в оптимизации.

Ответ 15

Мы попытались создать классы прокси один раз.

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

Ответ 16

В целом большие проекты на С++, над которыми я работал, имели медленное время сборки, были довольно грязными, с множеством взаимозависимостей, разбросанных по коду (те же самые файлы, используемые в большинстве cpps, толстые интерфейсы вместо тонких). В этих случаях медленное время сборки было всего лишь симптомом большей проблемы и незначительным симптомом. Рефакторинг для создания более четких интерфейсов и выхода из кода в библиотеки улучшил архитектуру, а также время сборки. Когда вы создаете библиотеку, это заставляет вас думать о том, что такое интерфейс, а что нет, что на самом деле (по моему опыту) улучшит базу кода. Если нет никакой технической причины, чтобы разделить код, некоторые программисты в ходе обслуживания просто бросают что-либо в любой заголовочный файл.

Ответ 17

Cătălin Pitiş покрыл много хороших вещей. Другие, которые мы делаем:
  • У вас есть инструмент, который генерирует уменьшенные файлы Visual Studio.sln для людей, работающих в определенной суб-области очень большого общего проекта.
  • Cache DLL и pdbs с момента их создания на CI для распространения на машинах разработчика.
  • Для CI убедитесь, что на узле связи в частности есть много памяти и высокопроизводительных дисков.
  • Храните некоторые дорогостоящие файлы в исходном элементе управления, даже если они могут быть созданы как часть сборки
  • Замените проверку Visual Studio того, что нужно переделать с помощью нашего собственного script, адаптированного к нашим условиям.

Ответ 18

Это мое домашнее животное, так что, хотя вы уже приняли отличный ответ, я буду звонить:

В С++ это меньше язык как таковой, но язык, построенный на языке, который отлично зарекомендовал себя в семидесятых годах, и библиотеки с большими заголовками.

Единственное, что неверно в ответе Cătălin Pitiş: "покупать более быстрые машины" должно идти первым. Это самый простой способ с наименьшим воздействием.

Мое худшее было около 80 минут на стареющей машине для сборки VC6 на W2K Professional. Тот же проект (с тоннами нового кода) теперь занимает менее 6 минут на машине с четырьмя гиперпотоковыми ядрами, 8G RAM Win 7 x64 и приличными дисками. (Аналогичная машина, на 10,20% меньше мощности процессора, с 4G RAM и Vista x86 занимает вдвое больше времени)

Странно, инкрементные сборки в большинстве случаев медленнее, чем полные перестройки.

Ответ 19

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

Ответ 20

Создайте несколько проектов unit test для тестирования отдельных библиотек, так что если вам нужно отредактировать классы низкого уровня, которые вызовут огромную перестройку, вы можете использовать TDD, чтобы узнать, как работает ваш новый код, прежде чем перестраивать все приложение. В книге Джона Лакоса, упомянутой Themis, есть несколько практических рекомендаций по реструктуризации ваших библиотек, чтобы сделать это возможным.