Мы получаем очень медленное время компиляции, которое может занимать более 20 минут на двухъядерных машинах с тактовой частотой 2 ГГц и 2G Ram.
Во многом это связано с размером нашего решения, которое выросло до 70+ проектов, а также с VSS, который сам по себе является узким местом, когда у вас много файлов. (замена VSS, к сожалению, не вариант, поэтому я не хочу, чтобы это переходило в Bash VSS)
Мы рассматриваем объединение проектов. Мы также ищем несколько решений для достижения большего разделения проблем и сокращения времени компиляции для каждого элемента приложения. Я вижу, это превратится в ад для DLL, поскольку мы пытаемся синхронизировать вещи.
Мне интересно узнать, как другие команды справились с этой проблемой масштабирования, что вы делаете, когда ваша кодовая база достигает критической массы, на которую вы тратите половину дня, наблюдая, как строка состояния доставляет сообщения компиляции.
ОБНОВЛЕНИЕ Я забыл упомянуть, что это решение C #. Спасибо за все предложения C ++, но прошло несколько лет с тех пор, как мне приходилось беспокоиться о заголовках.
РЕДАКТИРОВАТЬ:
Хорошие предложения, которые помогли до сих пор (не говоря уже о том, что ниже нет других хороших предложений, просто то, что помогло)
- Новый ноутбук с тактовой частотой 3 ГГц - сила потери нагрузки творит чудеса, когда мы обращаемся к руководству
- Отключить антивирус во время компиляции
- «Отключение» от VSS (на самом деле сети) во время компиляции - я могу заставить нас полностью удалить интеграцию VS-VSS и придерживаться пользовательского интерфейса VSS.
По-прежнему не копирует компиляцию, но помогает каждый бит.
Орион упомянул в комментарии, что у дженериков тоже может быть игра. Мои тесты показывают, что производительность минимальна, но недостаточно высока, чтобы быть уверенным - время компиляции может быть нестабильным из-за активности диска. Из-за ограничений по времени мои тесты не включали столько универсальных шаблонов или столько кода, сколько могло бы появиться в реальной системе, так что это могло накапливаться. Я бы не стал избегать использования дженериков там, где они должны использоваться, только для производительности во время компиляции.
Временное решение
Мы тестируем практику создания новых областей приложения в новых решениях, при необходимости импортируя новейшие библиотеки DLL и интегрируя их в более крупное решение, когда мы довольны ими.
Мы также можем сделать то же самое с существующим кодом, создав временные решения, которые просто инкапсулируют области, над которыми нам нужно работать, и выбрасывая их после реинтеграции кода. Нам нужно взвесить время, необходимое для реинтеграции этого кода, и время, которое мы выиграем, не имея опыта быстрой перекомпиляции в процессе разработки, как у Рипа Ван Винкля.
источник
Ответы:
Команда Chromium.org перечислила несколько вариантов ускорения сборки (на этом этапе примерно на полпути вниз по странице):
источник
У нас есть почти 100 проектов в одном решении, а время сборки составляет всего секунды :)
Для местного развития строит мы создали Visual Studio надстройки , что изменения
Project references
вDLL references
и разгружает нежелательные проекты (и возможность переключать их обратно, конечно).Наши сборки теперь занимают всего несколько секунд, когда мы работаем только над несколькими проектами одновременно. Мы также можем отлаживать дополнительные проекты, поскольку они связаны с отладочными библиотеками DLL. Инструмент обычно занимает 10-30 секунд, чтобы внести большое количество изменений, но вам не нужно делать это так часто.
Обновление май 2015
Сделка, которую я заключил (в комментариях ниже), заключалась в том, что я выпущу плагин с открытым исходным кодом, если он вызовет достаточный интерес. Спустя 4 года у него всего 44 голоса (а у Visual Studio теперь есть две последующие версии), так что в настоящее время это проект с низким приоритетом.
источник
У меня была аналогичная проблема с решением с 21 проектом и 1/2 миллиона LOC. Самая большая разница заключалась в получении более быстрых жестких дисков. Из монитора производительности «Сред. Disk Queue 'значительно увеличился бы на ноутбуке, указывая на то, что жесткий диск был узким местом.
Вот некоторые данные об общем времени восстановления ...
1) Ноутбук, Core 2 Duo 2 ГГц, привод 5400 об / мин (не уверен в кеш-памяти. Был стандартным Dell inspiron).
Время восстановления = 112 секунд.
2) Настольный компьютер (стандартная версия), Core 2 Duo 2,3 ГГц, один диск 7200 об / мин, кэш 8 МБ.
Время восстановления = 72 секунды.
3) Desktop Core 2 Duo 3Ghz, один WD Raptor, 10000 об / мин
Время восстановления = 39 секунд.
Привод на 10 000 об / мин нельзя недооценивать. Сборки, где значительно быстрее плюс все остальное, как отображение документации, использование проводника файлов было заметно быстрее. Это был большой прирост производительности за счет ускорения цикла создания кода и выполнения.
Учитывая, что компании тратят на заработную плату разработчиков, безумно, сколько они могут потратить впустую на покупку, оснащая их теми же компьютерами, что и администратор.
источник
Для сборок C # .NET вы можете использовать .NET Demon . Это продукт, который берет на себя процесс сборки Visual Studio, чтобы сделать его быстрее.
Он делает это путем анализа внесенных вами изменений и строит только тот проект, который вы действительно изменили, а также другие проекты, которые фактически основывались на внесенных вами изменениях. Это означает, что если вы измените только внутренний код, нужно будет построить только один проект.
источник
Выключи свой антивирус. Это увеличивает время компиляции.
источник
Используйте распределенную компиляцию. Xoreax IncrediBuild может сократить время компиляции до нескольких минут.
Я использовал его в огромном решении C \ C ++, компиляция которого обычно занимает 5-6 часов. IncrediBuild помог сократить это время до 15 минут.
источник
Инструкции по сокращению времени компиляции Visual Studio до нескольких секунд
К сожалению, Visual Studio недостаточно умен, чтобы отличить изменения интерфейса сборки от несущественных изменений тела кода. Этот факт в сочетании с большим количеством взаимосвязанных решений иногда может создавать идеальный шторм нежелательных «полных сборок» почти каждый раз, когда вы меняете одну строку кода.
Стратегия преодоления этого заключается в отключении автоматического построения дерева ссылок. Для этого используйте Configuration Manager (Build / Configuration Manager ... затем в раскрывающемся списке Active solution configuration выберите New), чтобы создать новую конфигурацию сборки с именем ManualCompile, которая копирует из конфигурации Debug, но не устанавливайте флажок "Создать новые конфигурации проекта". В этой новой конфигурации сборки снимите отметки с каждого проекта, чтобы ни один из них не был построен автоматически. Сохраните эту конфигурацию, нажав «Закрыть». Эта новая конфигурация сборки добавляется в ваш файл решения.
Вы можете переключаться с одной конфигурации сборки на другую с помощью раскрывающегося списка конфигурации сборки в верхней части экрана IDE (на котором обычно отображается «Отладка» или «Выпуск»). Фактически, эта новая конфигурация сборки ManualCompile сделает бесполезными пункты меню «Сборка» для «Построить решение» или «Перестроить решение». Таким образом, когда вы находитесь в режиме ManualCompile, вы должны вручную создать каждый проект, который вы изменяете, что можно сделать, щелкнув правой кнопкой мыши каждый затронутый проект в обозревателе решений и выбрав «Сборка» или «Перестроить». Вы должны увидеть, что общее время компиляции теперь будет составлять всего несколько секунд.
Чтобы эта стратегия работала, необходимо, чтобы VersionNumber, находящийся в файлах AssemblyInfo и GlobalAssemblyInfo, оставался статическим на компьютере разработчика (конечно, не во время сборок выпуска), и чтобы вы не подписывали свои библиотеки DLL.
Потенциальный риск использования этой стратегии ManualCompile заключается в том, что разработчик может забыть скомпилировать необходимые проекты, и при запуске отладчика они получают неожиданные результаты (невозможно подключить отладчик, файлы не найдены и т. Д.). Чтобы избежать этого, вероятно, лучше всего использовать конфигурацию сборки «Отладка» для компиляции большего объема кода и использовать конфигурацию сборки ManualCompile только во время модульного тестирования или для внесения быстрых изменений, которые имеют ограниченный объем.
источник
Если это C или C ++, и вы не используете предварительно скомпилированные заголовки, вам следует их использовать.
источник
У нас было более 80 проектов в нашем основном решении, создание которых заняло от 4 до 6 минут, в зависимости от того, на какой машине работал разработчик. Мы посчитали, что это слишком долго: каждый тест действительно съедает ваши FTE.
Итак, как сократить время сборки? Как вы, кажется, уже знаете, именно количество проектов сильно ухудшает время сборки. Конечно, мы не хотели избавляться от всех наших проектов и просто объединять все исходные файлы в один. Но у нас было несколько проектов, которые мы, тем не менее, могли объединить: поскольку каждый «проект репозитория» в решении имел свой собственный проект unittest, мы просто объединили все проекты unittest в один проект global-unittest. Это сократило количество проектов примерно до 12 и каким-то образом сэкономило 40% времени на создание всего решения.
Однако мы думаем о другом решении.
Вы также пробовали настроить новое (второе) решение с новым проектом? Это второе решение должно просто включать все файлы, использующие папки решения. Потому что вы можете быть удивлены, увидев время сборки этого нового решения с одним проектом.
Однако работа с двумя разными решениями требует особого внимания. Разработчики могут быть склонны фактически работать над вторым решением и полностью игнорировать первое. Поскольку первое решение с более чем 70 проектами будет решением, которое заботится о вашей иерархии объектов, это должно быть решение, в котором ваш сервер сборки должен запускать все ваши модульные тесты. Таким образом, сервер для непрерывной интеграции должен быть первым проектом / решением. Вы должны поддерживать свою объектную иерархию, верно.
Второе решение с одним проектом (который будет строиться намного быстрее) будет, чем проект, в котором тестирование и отладка будут выполняться всеми разработчиками. Однако вы должны позаботиться о них, глядя на сервер сборки! Если что-то сломается, это ДОЛЖНО быть исправлено.
источник
Убедитесь, что ваши ссылки являются ссылками на проекты, а не напрямую на библиотеки DLL в выходных каталогах библиотеки.
Кроме того, установите для них запрет на локальное копирование, кроме случаев крайней необходимости (главный проект EXE).
источник
Первоначально я разместил этот ответ здесь: /programming/8440/visual-studio-optimizations#8473. На этой странице можно найти много других полезных советов.
Если вы используете Visual Studio 2008, вы можете скомпилировать с помощью флага / MP для параллельной сборки одного проекта. Я читал, что это тоже недокументированная функция в Visual Studio 2005, но никогда не пробовал.
Вы можете строить несколько проектов параллельно, используя флаг / M, но обычно он уже установлен на количество доступных ядер на машине, хотя я считаю, что это применимо только к VC ++.
источник
Я заметил, что этот вопрос давний, но тема по-прежнему актуальна. Та же проблема укусила меня в последнее время, и две вещи, которые больше всего улучшили производительность сборки: (1) использовать выделенный (и быстрый) диск для компиляции и (2) использовать одну и ту же папку вывода для всех проектов и установить для CopyLocal значение False в проекте. Ссылки.
Некоторые дополнительные ресурсы:
источник
Некоторые инструменты анализа:
tools-> options-> Настройки проекта VC ++ -> Build Timing = Yes сообщит вам время сборки для каждого vcproj.
Добавьте
/Bt
переключатель в командную строку компилятора, чтобы увидеть, сколько занимает каждый файл CPPИспользуйте,
/showIncludes
чтобы перехватить вложенные включения (файлы заголовков, которые включают другие файлы заголовков) и посмотреть, какие файлы могут сэкономить много операций ввода-вывода с помощью форвардных объявлений.Это поможет вам оптимизировать производительность компилятора, устранив зависимости и проблемы с производительностью.
источник
Прежде чем тратить деньги на приобретение более быстрых жестких дисков, попробуйте построить свой проект полностью на RAM-диске (при условии, что у вас есть свободная RAM). Вы можете найти в сети различные бесплатные драйверы для RAM-диска. Вы не найдете ни одного физического диска, в том числе SSD, который был бы быстрее RAM-диска.
В моем случае проект, на создание которого потребовалось 5 минут на 6-ядерном i7 на диске SATA 7200 об / мин с Incredibuild, был сокращен всего на 15 секунд за счет использования RAM-диска. Учитывая необходимость повторного копирования в постоянное хранилище и возможность потери работы, 15 секунд - недостаточный стимул для использования RAM-диска и, вероятно, не большой стимул потратить несколько сотен долларов на высокоскоростной или SSD-накопитель.
Небольшой прирост может указывать на то, что сборка была привязана к ЦП или что кеширование файлов Windows было довольно эффективным, но поскольку оба теста проводились из состояния, когда файлы не были кэшированы, я сильно склоняюсь к компиляциям с привязкой к ЦП.
В зависимости от фактического кода, который вы компилируете, ваш пробег может отличаться - так что не стесняйтесь тестировать.
источник
Насколько велик ваш каталог сборки после завершения сборки? Если вы придерживаетесь настройки по умолчанию, то каждая сборка, которую вы создаете, будет копировать все библиотеки DLL своих зависимостей и зависимостей зависимостей и т. Д. В свой каталог bin. В моей предыдущей работе, когда я работал с решением для ~ 40 проектов, мои коллеги обнаружили, что самой дорогой частью процесса сборки было многократное копирование этих сборок, и что одна сборка может генерировать гигабайты копий одних и тех же DLL снова и снова. снова.
Вот несколько полезных советов от Патрика Смаккиа, автора NDepend, о том, что, по его мнению, должно и не должно быть отдельными сборками:
http://codebetter.com/patricksmacchia/2008/12/08/advices-on-partitioning-code-through-net-assemblies/
Есть два основных способа обойти это, и оба имеют недостатки. Один из них - уменьшить количество сборок, что, очевидно, требует больших усилий. Другой вариант - реструктурировать каталоги сборки так, чтобы все папки bin были объединены, а проекты не копировали библиотеки DLL своих зависимостей - в этом нет необходимости, потому что все они уже находятся в одном каталоге. Это значительно сокращает количество файлов, создаваемых и копируемых во время сборки, но это может быть сложно настроить и может вызвать некоторые трудности при извлечении только тех DLL, которые требуются конкретному исполняемому файлу для упаковки.
источник
Возможно, возьмите некоторые общие функции и сделайте несколько библиотек, чтобы одни и те же исходники не компилировались снова и снова для нескольких проектов.
Если вас беспокоит, что разные версии DLL перепутаются, используйте статические библиотеки.
источник
Отключите интеграцию VSS. У вас может не быть выбора в его использовании, но библиотеки DLL все время «случайно» переименовываются ...
И обязательно проверьте настройки предварительно скомпилированного заголовка. Руководство Брюса Доусона немного устарело, но все же очень хорошее - проверьте его: http://www.cygnus-software.com/papers/precompiledheaders.html
источник
У меня есть проект, который имеет 120 или более exes, libs и dll и требует значительного времени для создания. Я использую дерево командных файлов, которое вызывает создание файлов из одного основного командного файла. В прошлом у меня были проблемы со странностями из инкрементальных (или они были темпераментными) заголовками, поэтому я избегаю их сейчас. Я редко делаю полную сборку и обычно оставляю ее до конца дня, пока иду на прогулку в течение часа (поэтому я могу только догадываться, что это займет около получаса). Так что я понимаю, почему это невозможно для работы и тестирования.
Для работы и тестирования у меня есть другой набор командных файлов для каждого приложения (или модуля или библиотеки), в котором также есть все параметры отладки, но они все равно вызывают одни и те же файлы make. Я могу время от времени включать и выключать DEBUG, а также принимать решение о сборке или сборке или о том, хочу ли я также создавать библиотеки, от которых может зависеть модуль, и так далее.
Пакетный файл также копирует завершенный результат в (или несколько) тестовых папок. В зависимости от настроек это занимает от нескольких секунд до минуты (а не полчаса).
Я использовал другую IDE (Zeus), так как мне нравится контролировать такие вещи, как файлы .rc, и на самом деле я предпочитаю компилировать из командной строки, даже если я использую компиляторы MS.
С радостью выложу пример этого командного файла, если кому-то интересно.
источник
Отключите индексирование файловой системы в ваших исходных каталогах (в частности, в каталогах obj, если вы хотите, чтобы ваш источник был доступен для поиска)
источник
Если это веб-приложение, установка для пакетной сборки значения true может помочь в зависимости от сценария.
Вы можете найти обзор здесь: http://weblogs.asp.net/bradleyb/archive/2005/12/06/432441.aspx
источник
Вы также можете проверить наличие циклических ссылок на проекты. Однажды для меня это было проблемой.
То есть:
Проект A ссылается на проект B
Проект B ссылается на проект C
Проект C ссылается на проект A
источник
Одна более дешевая альтернатива Xoreax IB - это использование так называемых сборок убер-файлов. По сути, это файл .cpp с
Затем вы компилируете модули uber вместо отдельных модулей. Мы видели время компиляции от 10-15 минут до 1-2 минут. Возможно, вам придется поэкспериментировать с тем, сколько #includes на файл Uber имеет смысл. Зависит от проектов. и т.д. Может быть вы включаете 10 файлов, может быть, 20.
Вы платите определенную сумму, поэтому будьте осторожны:
Это своего рода боль, но для проекта, который в значительной степени статичен с точки зрения новых модулей, первоначальная боль может того стоить. Я видел, как этот метод в некоторых случаях превосходил IB.
источник
Если это проект C ++, вам следует использовать предварительно скомпилированные заголовки. Это сильно влияет на время компиляции. Не уверен, что на самом деле делает cl.exe (без использования предварительно скомпилированных заголовков), похоже, он ищет множество заголовков STL во всех неправильных местах, прежде чем, наконец, перейти в правильное место. Это добавляет целые секунды к каждому компилируемому файлу .cpp. Не уверен, что это ошибка cl.exe или какая-то проблема STL в VS2008.
источник
Глядя на машину, на которой вы строите, оптимально ли она настроена?
Мы только что сократили время сборки нашего крупнейшего продукта корпоративного масштаба на C ++ с 19 часов до 16 минут , убедившись, что установлен правильный драйвер фильтра SATA.
Тонкий.
источник
В Visual Studio 2005 есть недокументированный переключатель / MP, см. Http://lahsiv.net/blog/?p=40 , который позволяет выполнять параллельную компиляцию на основе файлов, а не проектов. Это может ускорить компиляцию последнего проекта или, если вы компилируете один проект.
источник
При выборе ЦП: размер кэша L1, похоже, имеет огромное влияние на время компиляции. Кроме того, обычно лучше иметь 2 быстрых ядра, чем 4 медленных. Visual Studio не очень эффективно использует дополнительные ядра. (Я основываю это на своем опыте работы с компилятором C ++, но, вероятно, это также верно и для компилятора C #.)
источник
Я также теперь убежден, что есть проблема с VS2008. Я запускаю его на двухъядерном ноутбуке Intel с 3G Ram с выключенным антивирусом. Компиляция решения часто бывает довольно гладкой, но если я занимался отладкой, последующая перекомпиляция часто замедлялась до обхода. По непрерывному свету индикатора основного диска видно, что существует узкое место ввода-вывода на диске (вы тоже это слышите). Если я отменю сборку и завершу работу VS, активность диска прекратится. Перезапустите VS, перезагрузите решение, а затем перестройте, и это намного быстрее. Unitl в следующий раз
Я считаю, что это проблема с подкачкой памяти - VS просто исчерпывает память, и O / S начинает подкачку страниц, чтобы попытаться освободить место, но VS требует больше, чем может предоставить подкачка страниц, поэтому он замедляется до обхода. Я не могу придумать другого объяснения.
VS определенно не является инструментом RAD, не так ли?
источник
Ваша компания случайно не использует Entrust для своего решения PKI / Encryption? Оказывается, у нас была ужасная производительность сборки для довольно большого веб-сайта, созданного на C #, что занимало 7+ минут на Rebuild-All.
Моя машина - i7-3770 с оперативной памятью 16 ГБ и SSD на 512 ГБ, поэтому производительность не должна быть такой плохой. Я заметил, что время моей сборки было безумно быстрее на старом вторичном компьютере с той же кодовой базой. Поэтому я запустил ProcMon на обеих машинах, профилировал сборки и сравнил результаты.
И вот, у медленной машины было одно отличие - ссылка на Entrust.dll в трассировке стека. Используя эту недавно полученную информацию, я продолжил поиск в StackOverflow и обнаружил следующее: MSBUILD (VS2010) очень медленный на некоторых машинах . Согласно принятому ответу проблема заключается в том, что обработчик Entrust обрабатывал проверки сертификатов .NET вместо собственного обработчика Microsoft. Также предполагается, что Entrust v10 решит эту проблему, которая преобладает в Entrust 9.
В настоящее время он удален, и время сборки упало до 24 секунд . YYMV с количеством проектов, которые вы в настоящее время создаете, и не может напрямую решать проблему масштабирования, о которой вы спрашивали. Я опубликую изменение в этом ответе, если смогу внести исправление, не прибегая к удалению программного обеспечения.
источник
Конечно, есть проблема с VS2008. Потому что единственное, что я сделал, это установил VS2008 для обновления моего проекта, созданного с помощью VS2005. В моем решении всего 2 проекта. Он не большой. Компиляция с VS2005: 30 секунд Компиляция с VS2008: 5 минут
источник
Хорошие предложения, которые помогли до сих пор (не говоря уже о том, что ниже нет других хороших предложений, если у вас есть проблемы, я рекомендую прочитать то, что помогло нам)
По-прежнему не копирует компиляцию, но помогает каждый бит.
Мы также тестируем практику создания новых областей приложения в новых решениях, при необходимости импортируя новейшие библиотеки DLL и интегрируя их в более крупное решение, когда мы довольны ими.
Мы также можем сделать то же самое с существующим кодом, создав временные решения, которые просто инкапсулируют области, над которыми нам нужно работать, и выбрасывая их после реинтеграции кода. Нам нужно взвесить время, необходимое для реинтеграции этого кода, и время, которое мы выиграем, не имея опыта быстрой перекомпиляции в процессе разработки, как у Рипа Ван Винкля.
Орион упомянул в комментарии, что у дженериков тоже может быть игра. Мои тесты показывают, что производительность минимальна, но недостаточно высока, чтобы быть уверенным - время компиляции может быть нестабильным из-за активности диска. Из-за ограничений по времени мои тесты не включали столько универсальных шаблонов или столько кода, сколько могло бы появиться в реальной системе, так что это могло накапливаться. Я бы не стал избегать использования дженериков там, где они должны использоваться, только для производительности во время компиляции.
источник