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

Как уменьшить время MSBuild

Моя ситуация

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

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

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

  • Вызов постройки для декомпиляции/компиляции. (20%)

  • Выполнение фактической компиляции и т.д. (20%)

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

\loader\bin\loader.exe

\loader\plugin\plugin1\plugin1.dll

\loader\plugin\plugin1\somedependency.dll

Что я сделал

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

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

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

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

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

Мой вопрос

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Вот мои впечатления:

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

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

Запустите свою сборку два раза с помощью диагностической многословия без каких-либо изменений в вашем коде и проверьте "полностью сконструировать цель" CoreCompile "как я описал здесь. Вы можете иметь что-то не так в ваших файлах проекта, и ваши проекты перекомпилируются каждый раз. Если вы ничего не измените, ваш журнал сборки не должен содержать" полностью настраиваемые "записи" Building target" CoreCompile.

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

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

  • /m: 4, отладка с анализом кода 1:38
  • /m: 1, отладка с анализом кода 1:30
  • /m: 4, отладка без анализа кода 1:30
  • /m: 1, отладка без анализа кода 1:30
  • /m: 1, Release с анализом кода: 1:30
  • /m: 4, Release с анализом кода: 1:05
  • /m: 4, Release без анализа кода: 0:53

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

Ответ 3

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

В отличие от большинства процессов, запущенных на машине сборки, процессы сборки печально известны как CPU, RAM и I/O-consuming. Общий рецепт ускорения сборки MSBuild - это "получить лучшие машинные деньги, которые можно купить", в частности:

  • CPU - как минимум два процессора Intel Core 2 Duo с тактовой частотой 3,0 ГГц.

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

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

  • Сеть - минимум 1 Gbit/s-карта.

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

Ответ 4

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

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