Visual Studio 2005编译时间非常慢

我们的编译时间非常慢,在双核2GHz,2G的Ram机器上可能需要20多分钟的时间。

这很大程度上是由于我们的解决scheme的规模已经增长到70多个项目,以及VSS本身就是瓶颈,当你有很多的文件。 (交换出VSS不是一个不幸的select,所以我不希望这下降到VSS bash)

我们正在考虑合并项目。 我们也正在寻求多种解决scheme来实现应用程序中每个元素的更多关注点和更快的编译时间。 当我们尝试保持同步时,我可以看到它将成为一个DLL地狱。

我很有兴趣知道其他团队如何处理这个扩展问题,当你的代码基数达到临界质量时,你会怎么做,你浪费了半天的时间来观察状态栏提供的编译信息。

更新我忽略提及这是一个C#解决scheme。 感谢所有C ++的build议,但是我不得不担心标题已经有几年了。

编辑:

很好的build议,迄今为止帮助(不说下面没有其他好的build议,只是有什么帮助)

  • 新的3GHz笔记本电脑 – 失去利用的力量的工作奇迹时,pipe理呜咽
  • 在编译期间禁用防病毒
  • 在编译期间断开与VSS(实际上是networking)的连接 – 我可能会让我们完全删除VS-VSS集成,并坚持使用VSS UI

仍然没有通过编译啜饮,但每一点都有帮助。

猎户座在一个评论中也提到了generics也可能有戏剧性。 从我的testing看来,这似乎是一个最小的性能影响,但还不足以确定 – 由于光盘活动,编译时间可能不一致。 由于时间限制,我的testing没有包含尽可能多的generics,也没有包含尽可能多的代码,就像在实时系统中出现的那样,这样可能会累积起来。 我不会避免使用他们应该使用的generics,只是为了编译时的性能

替代方法

我们正在testing在新解决scheme中构build应用程序新领域的做法,根据需要导入最新的dll,当我们满意时将它们集成到更大的解决scheme中。

我们也可以通过创build临时解决scheme来完成与现有代码相同的操作,这些临时解决scheme只是将需要处理的区域封装起来,并在重新集成代码后将其扔掉。 我们需要权衡重新整合这些代码的时间,而不是让Rip Van Winkle喜欢在开发过程中快速重新编译的经验。

Chromium.org团队列出了几个加速构build的选项(在这一点上大概是中途):

按加速顺序排列:

  • 安装Microsoft修补程序935225 。
  • 安装Microsoft修补程序947315 。
  • 使用真正的多核处理器(即Intel Core Duo 2;不是Pentium 4 HT)。
  • 使用3个并行版本。 在Visual Studio 2005中,您可以在工具>选项…>项目和解决scheme>构build和运行>最大并行项目构build数量中find该选项。
  • 禁用.ilk,.pdb,.cc,.h文件的防病毒软件,并仅在修改时检查病毒。 禁用扫描源代码所在的目录。 不要做任何愚蠢的事情。
  • 在第二个硬盘上存储和构buildChromium代码。 它不会真的加快构build,但至less你的电脑会保持响应,当你做gclient同步或构build。
  • 定期对硬盘进行碎片整理。
  • 禁用虚拟内存。

我们在一个解决scheme中有近100个项目,开发时间只有几秒钟:)

对于本地开发构build,我们创build了一个Visual Studio Addin,将Project references更改为DLL references并卸载不需要的项目(以及将其切换回去的选项)。

  • build立一个完整的解决scheme
  • 卸载我们当前没有工作的项目,并将所有项目引用更改为DLL引用。
  • 在签入之前,将所有的引用从DLL改回到项目引用。

当我们一次只做几个项目时,我们的构build只需要几秒钟的时间。 我们还可以在链接到debuggingDLL时debugging其他项目。 该工具通常需要10-30秒才能进行大量更改,但不必经常这样做。

2015年5月更新

我所做的交易(下面的评论)是, 如果获得足够的兴趣,我会将该插件发布到开源软件。 4年后,它只有44票(而Visual Studio现在有两个后续版本),所以它目前是一个低优先级的项目。

对于21个项目和150万个LOC的解决scheme,我也有类似的问题。 最大的不同是硬盘速度越来越快。 从性能监视器“平均。 “磁盘队列”将在笔记本电脑上显着跳跃,表明硬盘驱动器是瓶颈。

这里有一些数据的总重build时间…

1)笔记本电脑,Core 2 Duo 2GHz,5400 RPM驱动器(不确定的caching,是标准的戴尔inspiron)。

重build时间= 112秒。

2)桌面(标准问题),Core 2 Duo 2.3Ghz,单个7200RPM驱动器8MBcaching。

重build时间= 72秒。

3)台式机Core 2 Duo 3Ghz,单10000 RPM WD Raptor

重build时间= 39秒。

10000 RPM的驱动器不能低估。 build立在哪里显着更快,再加上一切如显示文档,使用文件浏览器是显而易见的更快。 通过加快代码生成周期,这是一个巨大的生产力提升。

考虑到公司在开发者工资方面的花费,他们可以用接待员使用的相同PC来浪费多less钱来购买设备。

对于C#.NET版本,您可以使用.NET Demon 。 这是一个接pipeVisual Studio构build过程以使其更快的产品。

它通过分析您所做的更改来完成此操作,并仅构build您实际更改的项目以及实际依赖于您所做更改的其他项目。 这意味着如果您只更改内部代码,则只需构build一个项目。

closures您的防病毒。 它增加了编译时间。

使用分布式编译。 Xoreax IncrediBuild可以将编译时间缩短到几分钟。

我在一个巨大的C \ C ++解决scheme上使用它,通常需要5-6个小时才能编译。 IncrediBuild帮助减less了15分钟的时间。

有关将Visual Studio编译时间缩短到几秒的说明

不幸的是Visual Studio不够聪明,不能区分程序集的界面变化和不重要的代码体变化。 这个事实,当与大量交织在一起的解决scheme结合在一起时,有时候会在几乎每次更改一行代码时都会产生一个完全不需要的“完整构build”的风暴。

解决这个问题的策略是禁用自动引用树构build。 要做到这一点,使用“configurationpipe理器”(构build/configurationpipe理器…然后在活动解决schemeconfiguration下拉菜单中select“新build”)创build一个名为“手动编译”的新构buildconfiguration,从debuggingconfiguration复制,不检查“创build新的项目configuration”checkbox。 在这个新的构buildconfiguration中,取消选中每个项目,以便它们都不会自动生成。 点击“closures”保存此configuration。 这个新的构buildconfiguration被添加到您的解决scheme文件。

您可以通过IDE屏幕(通常显示“Debug”或“Release”)的顶部的构buildconfiguration下拉菜单从一个构buildconfiguration切换到另一个构buildconfiguration。 实际上,这种新的ManualCompile构buildconfiguration将使“构build解决scheme”或“重build解决scheme”的“构build”菜单选项无效。 因此,当您处于ManualCompile模式时,必须手动构build您正在修改的每个项目,方法是右键单击解决scheme资源pipe理器中的每个受影响的项目,然后select“Build”或“Rebuild”。 你应该看到你的整体编译时间现在只是几秒钟。

为了使这个策略起作用,在AssemblyInfo和GlobalAssemblyInfo文件中find的VersionNumber在开发者的机器上保持静态(当然不是在发布版本期间),并且你不签名你的DLL。

使用此ManualCompile策略的潜在风险是开发人员可能会忘记编译所需的项目,并且当他们启动debugging器时,他们会得到意外的结果(无法附加debugging器,未find文件等)。 为了避免这种情况,最好使用“Debug”构buildconfiguration来编译更大的编码工作,并且只能在unit testing期间使用ManualCompile构buildconfiguration或进行范围有限的快速更改。

如果这是C或C ++,并且您没有使用预编译头文件,那应该是。

我们的主要解决scheme中有80多个项目需要花费大约4到6分钟时间,具体取决于开发人员的工作types。 我们认为这太长了:每一次testing都会让你的FTE吃光。

那么如何加快构build时间呢? 正如你似乎已经知道这是真正损害buildtime的项目数量。 当然,我们不想摆脱我们所有的项目,只是把所有的源文件合并成一个。 但是我们有一些项目可以合并:由于解决scheme中的每个“Repository项目”都有自己的unit testing项目,所以我们将所有的unit testing项目合并为一个全局unit testing项目。 减less了大约12个项目的项目数量,从而节省了40%的时间来构build整个解决scheme。

我们正在考虑另一个解决scheme。

你是否还试图用一个新项目来build立一个新的(第二个)解决scheme? 这第二个解决scheme应该简单地合并所有文件使用解决scheme文件夹 因为您可能会惊奇地发现新解决scheme的构build时间只有一个项目。

但是,使用两种不同的解决scheme需要仔细考虑。 开发人员可能倾向于在第二种解决scheme中实际工作,而完全忽视第一种解决scheme。 由于70+项目的第一个解决scheme将是解决scheme,照顾你的对象层次结构,这应该是你的构build服务器应该运行你所有的unit testing的解决scheme。 所以连续集成的服务器必须是第一个项目/解决scheme。 你必须维护你的对象层次结构。

只有一个项目的第二个解决scheme(它将更快地构build)比将由所有开发人员进行testing和debugging的项目要好。 你必须照顾他们看看buildserver! 如果有什么破的话必须修正。

确保您的引用是Project引用,而不是直接指向库输出目录中的DLL。

另外,除非绝对必要(主EXE项目),否则设置为不复制本地。

我原先在这里发布了这个响应: https : //stackoverflow.com/questions/8440/visual-studio-optimizations#8473你可以在该页面find许多其他有用的提示。

如果您使用Visual Studio 2008,则可以使用/ MP标志进行编译,以并行方式构build单个项目。 我已经读过,这也是Visual Studio 2005中的一个未logging的function,但从未尝试过自己。

您可以使用/ M标志并行地创build多个项目,但通常已经设置为机器上可用内核的数量,尽pipe这只适用于我相信的VC ++。

我注意到这个问题已经过时了,但是今天这个话题还是很有趣的。 同样的问题,最近我有点改变了,最大的改进build设性能的两件事情是(1)使用专用(和快速)磁盘进行编译和(2)使用相同的输出文件夹为所有项目,并将项目CopyLocal设置为False引用。

一些额外的资源:

一些分析工具:

tools-> options-> VC ++项目设置 – > Build Timing = Yes会告诉你每个vcproj的构build时间。

添加/Bt切换到编译器命令行查看每个CPP文件占用了多less

使用/showIncludes捕获嵌套包含(包含其他头文件的头文件),并查看哪些文件可以使用前向声明保存大量的IO。

这将通过消除依赖关系和性能浪费来帮助您优化编译器性能。

在花钱投资更快的硬盘驱动器之前,尝试在RAM磁盘上完全构build您的项目(假设您有RAM备用)。 您可以在网上find各种免费的RAM磁盘驱动程序。 您将找不到任何物理驱动器(包括SSD)比RAM磁盘更快。

就我而言,使用Incredibuild在7200 RPM SATA驱动器上花费5分钟构build6核i7的项目,通过使用RAM磁盘仅减less了大约15秒。 考虑到需要复制到永久存储和丢失工作的可能性,15秒是不够激励使用RAM磁盘,可能没有太多的激励花费数百美元的高RPM或SSD驱动器。

微小的增益可能表明构build是CPU绑定的,或者Windows文件caching是相当有效的,但是由于这两个testing都是在没有caching文件的状态下完成的,所以我严重依赖于CPU绑定的编译。

根据你编写的实际代码,你的里程可能会有所不同 – 所以不要犹豫,testing。

完成构build后,构build目录有多大? 如果你坚持使用默认设置,那么你构build的每个程序集都会将其依赖关系的所有DLL及其依赖关系的依赖关系等复制到它的bin目录中。 在我以前的工作中,当处理大约40个项目的解决scheme时,我的同事们发现,到目前为止,构build过程中最昂贵的部分是反复复制这些程序集,并且一个构build可以生成相同DLL的千兆字节拷贝再次。

以下是NDepend的作者Patrick Smacchia提供的一些有用的build议,他认为他应该而不应该是单独的程序集:

http://codebetter.com/patricksmacchia/2008/12/08/advices-on-partitioning-code-through-net-assemblies/

基本上有两种方法可以解决这个问题,并且都有缺点。 一个是减less组件数量,这显然是很多工作。 另一个是重新构build您的构build目录,以便所有的bin文件夹被整合,项目不会复制它们的依赖关系的dll – 他们不需要,因为它们都已经在同一个目录中了。 这大大减less了在构build过程中创build和复制的文件数量,但是设置起来可能会很困难,并且可能会让您遇到一些困难,只能提取特定可执行文件所需的DLL进行打包。

也许采取一些共同的function,并build立一些图书馆,这种方式相同的来源不被重复编译多个项目。

如果担心不同版本的DLL混淆,请使用静态库。

closuresVSS集成。 您可能没有select使用它,但DLL“意外”重新命名一直…

肯定检查你的预编译头文件设置。 Bruce Dawson的指南有点旧了,但还是不错的 – 查看一下: http : //www.cygnus-software.com/papers/precompiledheaders.html

我有一个项目,有120个以上的exs,libs和dll,需要花费相当多的时间来构build。 我使用从一个主batch file调用make文件的batch file树。 我从过去的增量(或者是脾气暴躁)标题中遇到了一些奇怪的问题,所以我现在就避免使用它们。 我经常做一个完整的构build,通常在一个小时的时间里走到一天结束,所以我只能猜测大概需要半个小时。 所以我明白为什么工作和testing是不可行的。

为了工作和testing,我还为每个应用程序(或模块或库)提供了另外一组batch file,这些文件也具有所有的debugging设置 – 但是这些仍然调用相同的make文件。 我可能会不时地切换DEBUG,也决定build立或者使我还想build立模块可能依赖的库,等等。

batch file还将完成的结果复制到(或几个)testing文件夹中。 根据不同的设置,这将在几秒到一分钟内完成(而不是半个小时)。

我使用了不同的IDE(Zeus),因为我喜欢对.rc文件进行控制,而且实际上更喜欢从命令行进行编译,即使我正在使用MS编译器。

如果有人感兴趣,很高兴发布这个batch file的例子。

禁用文件系统索引您的源目录(特别是obj目录,如果你想你的源search)

如果这是一个Web应用程序,根据情况设置批生成为true可以帮助。

 <compilation defaultLanguage="c#" debug="true" batch="true" > 

你可以在这里find一个概述: http : //weblogs.asp.net/bradleyb/archive/2005/12/06/432441.aspx

你也可能想检查循环项目的参考。 这对我来说是一个问题。

那是:

项目A参考项目B

项目B引用项目C

项目C引用项目A

Xoreax IB的一个更便宜的select是使用我称之为超级文件构build。 它基本上是一个.cpp文件

 #include "file1.cpp" #include "file2.cpp" .... #include "fileN.cpp" 

然后你编译uber单元而不是单个模块。 我们已经看到从10-15分钟到1-2分钟的编译时间。 你可能不得不体验每个超级文件有多less#includes是有意义的。 取决于项目。 等等。也许你包括10个文件,也许20个。

你要付出代价,所以要小心:

  1. 你不能右键单击一个文件,并说“编译…”,因为你必须从构build中排除单个cpp文件,只包含uber cpp文件
  2. 你必须小心静态全局variables冲突。
  3. 当你添加新的模块,你必须保持最新的uber文件

这是一种痛苦,但对于一个在新模块方面基本上是静态的项目来说,最初的痛苦可能是值得的。 在某些情况下,我见过这种方法击败了IB。

如果是C ++项目,那么你应该使用预编译头文件。 这在编译时间上有很大的不同。 不知道cl.exe究竟在做什么(没有使用预编译头文件),它似乎在最终到达正确的位置之前,在所有错误的地方寻找大量的STL头文件。 这会将整个秒数添加到正在编译的每个.cpp文件中。 不知道这是一个cl.exe错误,或VS2008中的某种types的STL问题。

看看你正在build设的机器,是最佳configuration?

通过确保安装正确的SATAfilter驱动程序,我们将我们最大的C ++企业级产品的构build时间从19小时缩短16分钟

微妙。

在Visual Studio 2005中没有文档/ MP开关,请参阅http://lahsiv.net/blog/?p=40 ,这将启用基于文件而不是项目基础的并行编译。 这可能会加速编译上一个项目,或者如果编译一个项目。

selectCPU时:L1caching大小似乎对编译时间有巨大的影响。 此外,通常有2个快速内核比4个慢速内核更好。 Visual Studio不会非常有效地使用额外的内核。 (我基于C ++编译器的经验,但对于C#编译器也可能是这样。)

我现在也确信VS2008有一个问题。 我正在使用3G Ram的双核英特尔笔记本电脑上运行它,并closures了防病毒function。 编译解决scheme通常是非常灵活的,但是如果我一直在debugging后续的重新编译,通常会慢下来。 从连续的主磁盘指示灯可以看出存在磁盘I / O瓶颈(您也可以听到)。 如果我取消构build和closuresVS,磁盘活动停止。 重新启动VS,重新加载解决scheme,然后重build,速度更快。 Unitl下次

我的想法是,这是一个内存分页问题 – VS只是内存不足,O / S开始页面交换,以尝试制作空间,但VS要求比页面交换可以提供更多的要求,所以它减慢爬行。 我想不出任何其他解释。

VS绝对不是一个RAD工具,是吗?

肯定VS2008有问题。 因为我所做的唯一的事情就是安装VS2008来升级我已经用VS2005创build的项目。 我的解决scheme中只有2个项目。 这不是很大。 使用VS2005编译:30 secondes使用VS2008编译:5分钟

好的build议,迄今为止帮助(不说下面没有其他好的build议,如果你有问题,我build议阅读,然后帮助我们)

  • 新的3GHz笔记本电脑 – 失去利用的力量的工作奇迹时,pipe理呜咽
  • 在编译期间禁用防病毒
  • 在编译期间断开与VSS(实际上是networking)的连接 – 我可能会让我们完全删除VS-VSS集成,并坚持使用VSS UI

仍然没有通过编译啜饮,但每一点都有帮助。

我们也在testing在新解决scheme中构build应用程序新领域的做法,根据需要导入最新的dll,在我们满意的时候将它们集成到更大的解决scheme中。

我们也可以通过创build临时解决scheme来完成与现有代码相同的操作,这些临时解决scheme只是将需要处理的区域封装起来,并在重新集成代码后将其扔掉。 我们需要权衡重新整合这些代码的时间,而不是让Rip Van Winkle喜欢在开发过程中快速重新编译的经验。

猎户座在一个评论中也提到了generics也可能有戏剧性。 从我的testing看来,这似乎是一个最小的性能影响,但还不足以确定 – 由于光盘活动,编译时间可能不一致。 由于时间限制,我的testing没有包含尽可能多的generics,也没有包含尽可能多的代码,就像在实时系统中出现的那样,这样可能会累积起来。 我不会避免使用他们应该使用的generics,只是为了编译时的性能

有几件事我发现有用的C#/.NET构build:

  • 将小型项目组合成更大型的项目,因为每个项目都需要花费大量的时间来构build解决scheme。 (如果需要,使用nDepend来控制跨层的呼叫)

  • 将我们所有的项目build立到一些输出目录中,然后在所有项目引用上将“copy local”设置为false – 由于减less了IO,这会导致大量的加速。

  • 打开你的病毒检查器,看看它是否有很大的区别; 如果这样find更快的病毒检查程序 ,或从病毒检查程序扫描中排除“热门”文件夹

  • 使用perforce监视器和sys内部工具来查看编译所花的时间。

  • 考虑一个内存盘来放置你的输出目录。

  • 考虑使用SSD

  • 更多的内存有时会产生很大的影响 – (如果你通过删除一个小内存来减慢内存的减速速度,你可以通过增加更多的内存来减less机器的内存)删除不需要的项目引用(你可能需要先删除不需要的“使用”)

  • 考虑为最低的域层使用dependency injection框架和接口,所以只有当接口发生变化时才需要重新编译所有内容 – 取决于接口更改的频率,这可能无法获得太多的收益。