Как уменьшить время MSBuild - PullRequest
17 голосов
/ 04 мая 2009

Моя ситуация

В проекте C #, над которым я сейчас работаю, у нас есть довольно большое решение (более 80 проектов). Теперь время восстановления 5 минут + действительно становится большой проблемой при использовании MSBuild из Visual Studio 2008 .

В анализе, который я провел на прошлой неделе, выяснилось, что мое время сборки было потрачено следующим образом:

  1. Копирование файлов в проекты и повторное копирование в проекты, которые зависят от него (CopyToLocal) и т. Д. (60%)

  2. Вызов postbuild для декомпиляции / компиляции. (20%)

  3. Выполнение актуальной компиляции и т. Д. (20%)

Помимо «нормального» проекта, вывод папок bin\debug также копируется во внешний каталог для настройки основной программы «загрузчик». Основная структура программы выглядит примерно так:

\loader\bin\loader.exe

\loader\plugin\plugin1\plugin1.dll

\loader\plugin\plugin1\somedependency.dll

Что я сделал

В попытке ускорить процесс я подумал о следующем:

  1. Скопируйте все файлы в один большой каталог и не используйте CopyTolocal . Мне это не нравится, потому что мы больше не можем использовать разные версии одних и тех же DLL-файлов, и моя папка bin находится в беспорядке.

  2. Использовать параллелизм (/ m) для MSBuild . Это очень мало помогает во время сборки.

  3. Попробуйте уменьшить зависимости между проектами, что, конечно, всегда хорошо.

  4. Инвестируйте в оборудование. Я нашел исследование твердотельных накопителей , но это не кажется многообещающим.

Мой вопрос

Я также заметил, что при внесении изменений в проект, который находится в корне моего дерева зависимостей, все перестраивается. Даже если изменение было только в «приватной» части, и интерфейс проекта не изменился.

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

Можно ли это изменить в другое состояние? Например, контрольная сумма файла?

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

Ответы [ 4 ]

24 голосов
/ 30 октября 2011

Я работаю над 500+ проектами приложений на C #. Проекты компилируются параллельно, а copylocal устанавливается в false. Время компиляции составляет около 37 минут без юнит-тестов и покрытия кода. 13 минут для инкрементной сборки без каких-либо изменений в коде.

Если я выключу параллельную компиляцию и установлю copylocal в значение true, время компиляции составит 1 ч 40 мин.

У меня другая конфигурация для локальной сборки, сборок gated-check и сборок сервера с фазой развертывания (ночные сборки).

Вот мой опыт:

  1. Копирование выходных файлов в один каталог не является хорошей идеей, если вы хотите строить свои проекты параллельно, если для CopyLocal не задано значение false. Мои сборки иногда блокировались, когда несколько проектов ссылались на одну и ту же сборку, и MSBuild пытался одновременно скопировать эту ссылку в выходную папку. Это решение было очень полезно для меня. Я установил для copylocal значение false для всех ссылок, и размер моего каталога компоновки был уменьшен в 10 раз (в 10 раз меньше операций ввода-вывода). У меня есть разные настройки для локальной сборки и для сборки сервера. Различные настройки для сборки с закрытой регистрацией и для полной сборки развертывания.
  2. Если я включу параллельную сборку, сборка будет быстрее, намного быстрее. Если у вас сильный сервер сборки, ваша сборка /m:2 должна быть в 2 раза быстрее, чем сборка /m:1. Это не имеет никакого отношения к зависимостям между проектами (если copylocal имеет значение false).
  3. Вам следует уменьшить зависимости между проектами, если вы хотите иметь быструю инкрементную сборку. Это не влияет на полную сборку (copylocal false). Время инкрементной компиляции зависит от измененного местоположения проекта в дереве сборки.

Да, MSBuild использует временную метку зависимых проектов, чтобы определить, нуждается ли проект в перестройке. Он сравнивает временные метки входных файлов (файлы кода, ссылочные сборки, временные файлы и т. Д.) С выходной сборкой. Если что-то изменилось, ваш проект перекомпилирован. Попробуйте уменьшить количество зависимостей между проектами, чтобы минимизировать перекомпиляцию. Если ваше изменение было только в «частной» части проекта, ваша выходная сборка будет изменена, метка времени сборки будет изменена, и все связанные проекты также будут перестроены. С этим ничего не поделаешь.

Выполните сборку два раза с подробным диагностическим описанием без каких-либо изменений в коде и проверьте «Полное построение целевого« CoreCompile »», как я описал здесь . В файлах вашего проекта может быть что-то не так, и ваши проекты каждый раз перекомпилируются. Если вы ничего не измените, ваш журнал сборки не должен содержать журналы «Цель сборки« CoreCompile »полностью».

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

Если у вас много ГБ ОЗУ, попробуйте использовать его как жесткий диск в памяти. Ваша сборка должна быть намного быстрее:)

SSD-накопители чувствительны к высокой скорости ввода-вывода в день. Это влияет на гарантию.

Надеюсь, это кому-нибудь поможет ...;)

3 голосов
/ 09 мая 2009

У нас также есть огромные решения. Сборка и компиляция - все о вводе / выводе.

Твердотельные накопители очень перспективны. Сотрудник вставил твердотельный накопитель в свой ноутбук и обнаружил, что он теперь намного быстрее, чем его огромная основная коробка разработки. У меня нет подробностей, но он утверждает, что во много раз быстрее.

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

/m редко помогает в отладочных сборках .NET . Я провел серию тестов по этому вопросу несколько недель назад и обнаружил незначительные различия. Выводы:

  • Поскольку моя сборка ограничена вводом / выводом, использование / m: 2-4 делает отладочные сборки медленнее для меня.
  • Релиз строит обычно намного быстрее.
  • Анализ кода добавляет много времени.

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

На сервере сборки все сложнее. Мы думаем о настройке параллельной сборки CruiseControl.NET на различных машинах. Мы используем сборку VSTS, но это слишком дорого (и требует много времени) для горизонтального масштабирования, как это.

Мои номера для людей, ориентированных на детали. Конфигурации от самой медленной до самой быстрой, запускается msbuild "bigsolution.sln" / target: clean - между каждым.

  1. / м: 4, отладка с анализом кода 1: 38
  2. / м: 1, отладка с анализом кода 1: 30
  3. / м: 4, отладка без анализа кода 1: 30
  4. / м: 1, отладка без анализа кода 1: 30
  5. / м: 1, выпуск с анализом кода: 1: 30
  6. / м: 4, выпуск с анализом кода: 1: 05
  7. / м: 4, выпуск без анализа кода: 0: 53

Время сборки без перестроения или очистки: ~ 4-10 секунд

1 голос
/ 18 ноября 2009

Время сборки MSBuild - это многомерная проблема. Хорошая новость, которую легко решить:

В отличие от большинства процессов, выполняющихся на сборочной машине, процессы сборки печально известны тем, что потребляют ресурсы ЦП, ОЗУ и ввода-вывода. Общий рецепт для ускорения сборок MSBuild - «получи лучшую машину, которую можно купить за деньги», в частности:

  1. Процессор - как минимум два Intel 3,0 ГГц Core 2 Duo.

  2. RAM - не менее 4 ГБ DDR3. Если это компьютер разработчика и , лучше использовать 64-разрядную ОС и 8 ГБ ОЗУ.

  3. HDD - Самый быстрый вариант - это высокопроизводительный 3ware RAID-1 с встроенной батареей и включенным кешем записи. Быстрый SSD может быть другой вариант для рассмотрения.

  4. Сеть - минимальная карта 1 Гбит / с.

Эта простая аппаратная оптимизация может ускорить ваши MSBuilds в 2-3 раза.

0 голосов
/ 04 февраля 2016

Если у вас достаточно ОЗУ и вы используете Visual C ++ (не уверены в C #), вы можете ускорить процесс, скопировав весь каталог include и lib на диск RAM.

Вы также можете разместить временные элементы сборки на диске RAM. Конечно, вам нужно огромное количество оперативной памяти. Для включений и библиотек будет достаточно 2 ГБ ОЗУ. Но для временных файлов (* .obj и т. Д.) Это будет зависеть от проекта. Так что это может быть от 1 до 4 ГБ или больше.

...