Performance 改进构建/编译时间的方法有哪些?
我正在使用VisualStudio,似乎摆脱了未使用的引用和使用语句可以加快我在大型项目上的构建时间。是否有其他已知的加快构建时间的方法。其他语言和构建环境如何 构建/编译期间的瓶颈通常是什么?磁盘、CPU、内存Performance 改进构建/编译时间的方法有哪些?,performance,language-agnostic,build-process,build,Performance,Language Agnostic,Build Process,Build,我正在使用VisualStudio,似乎摆脱了未使用的引用和使用语句可以加快我在大型项目上的构建时间。是否有其他已知的加快构建时间的方法。其他语言和构建环境如何 构建/编译期间的瓶颈通常是什么?磁盘、CPU、内存 什么是分布式版本的良好参考列表?修复编译器警告应该会有很大帮助。Visual Studio支持并行版本,这会有所帮助,但真正的瓶颈是磁盘IO 例如,在C语言中-如果生成LST文件,编译将花费很长时间。不要在打开调试的情况下编译。请阅读本书。在物理结构方面,这是一个非常好的话题,你可以用
什么是分布式版本的良好参考列表?修复编译器警告应该会有很大帮助。Visual Studio支持并行版本,这会有所帮助,但真正的瓶颈是磁盘IO
例如,在C语言中-如果生成LST文件,编译将花费很长时间。不要在打开调试的情况下编译。请阅读本书。在物理结构方面,这是一个非常好的话题,你可以用最少的重建将项目转换成不同的文件 不幸的是,它是在模板变得如此重要之前编写的。在C++编译时,模板是实时杀手。特别是如果你犯了错误,到处使用智能指针。在这种情况下,您只能不断升级到最新的CPU和最新的SSD驱动器。MSVC已经是FaSTists现有的C++编译器,如果使用预编译的头文件。p>
在我以前的工作中,我们在编译时间方面遇到了很大的问题,我们使用的策略之一就是信封模式 基本上,它试图通过最小化头大小来最小化预处理器在头中复制的代码量。它通过将非公共的内容移动到私有的friend类来实现这一点,下面是一个例子 foo.h:
class FooPrivate;
class Foo
{
public:
Foo();
virtual ~Foo();
void bar();
private:
friend class FooPrivate;
FooPrivate *foo;
};
foo.cpp:
Foo::Foo()
{
foo = new FooPrivate();
}
class FooPrivate
{
int privData;
char *morePrivData;
};
您这样做的包含文件越多,它所包含的内容就越多。它确实有助于缩短编译时间
这确实使在VC6中调试变得困难,尽管我从中学到了这一点。有一个原因,它是以前的工作。 < P>我们为我们的大型C++项目所做的最大改进是发布我们的构建。几年前,完整构建大约需要半小时,而现在大约需要三分钟,其中三分之一是链接时间
我们使用的是一个专有的构建系统,但IncredBuild对很多人来说运行良好(我们无法让它可靠地工作)。如果您使用了大量文件和大量模板代码(STL/BOOST/等),那么批量构建或Unity构建应该减少构建和链接时间 批量构建的思想是将项目分解为多个子部分,并将该子部分中的所有CPP文件包含到单个文件中。Unity builds通过编译一个包含所有其他CPP文件的CPP文件进一步实现了这一点 这通常更快的原因是: 1) 每个大容量文件只对模板求值一次 2) 每个大容量文件只打开/处理一次包含文件(假设包含文件中有适当的
\ifndef File\uuuu FILENAME\uuu H/#define File\uu FILENAME\uu H/#endif
包装器)。减少总I/O对于编译时间来说是一件好事
3) 链接器要处理的数据要少得多(单个Unity OBJ文件或几个大容量OBJ文件),并且不太可能分页到虚拟内存
编辑添加有关Unity Builds的此处堆栈溢出的设置。注意项目中广泛的“考虑此目录和所有子目录以包含标题”类型设置。这将导致编译器不得不迭代每个目录直到找到请求的头文件,并且对于您在项目中包含的许多头文件来说,这可能是一个非常昂贵的操作。 < P> C++的瓶颈是磁盘I/O。这会导致为每个编译单元打开和读取大量文件 如果将源移动到RAM磁盘中,则可以获得显著的改进。如果您确保源文件只被读取一次,则情况会更糟 因此,对于新项目,我开始将所有内容都包含在一个文件中,我称之为
\uuuu.cpp
。它的结构是这样的:
/* Standard headers */
#include <vector>
#include <cstdio>
//...
/* My global macros*/
#define MY_ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0]))
// My headers
#include "foo.h"
#include "bar.h"
//...
// My modules
#include "foo.cpp"
#include "bar.cpp"
/*标准标题*/
#包括
#包括
//...
/*我的全局宏*/
#定义我的数组大小(X)(sizeof(X)/sizeof(X[0]))
//我的标题
#包括“foo.h”
#包括“bar.h”
//...
//我的模块
#包括“foo.cpp”
#包括“bar.cpp”
我只编译了一个文件
我的头文件和源文件不包含任何内容,并使用名称空间来避免与其他模块发生冲突
每当我的程序遗漏某些内容时,我只将其头和源添加到此模块中
通过这种方式,每个源文件和头只读取一次,并且构建速度非常快。编译时间随着文件的增加而线性增加,而不是二次增加。我的爱好是大约40000个loc和500个模块,但仍然编译大约10-20秒。如果我将所有源和头移动到RAM磁盘中,编译时间将减少到3秒
这样做的缺点是,现有的代码库很难重构以使用此方案 对于C#-为程序集使用固定版本,而不是自动增量版本,可以大大加快后续本地生成的速度
assemblyinfo.cs
// takes longer to update version number changes on all references to this assembly
[assembly: AssemblyVersion("1.0.*")]
// this way already built assemblies do not need to be recompiled
// to update version number changes.
[assembly: AssemblyVersion("1.0.0.0")]
<>编译时间和脆性基类问题:我写了一篇博客,介绍一种改进C++中编译时间的方法。p> 事实上,这不是语言不可知论。不同的语言对编译器有不同的要求,这会显著影响编译时间,没错,但我的问题更多的是如何在不同的编译器、环境、语言等中提高性能。。我通常使用VisualStudio,但有时使用msbuild、perl等,只有在他使用“cl”命令行工具时才使用。将stdout写入文件并不慢——即使在Windows上也是如此。我只是好奇这是否仅仅是因为将它们写入日志文件导致了速度减慢,所以如果没有什么警告,或者没有瓶颈,那就不重要了?有任何链接支持这一点吗?我们的程序生成5000多个编译器wa