使用模板时,如何处理越来越长的编译时间?


13

我使用Visual Studio 2012,在某些情况下,我们将模板参数添加到“ just”类中​​以引入“接缝点”,以便在单元测试中可以将这些部分替换为模拟对象。

您通常如何在C ++中引入接缝点:使用接口和/或通过使用模板参数,还基于某些条件与隐式接口进行混合?提出此问题的原因之一还在于,当有时编译单个C ++文件(包括模板文件,还可能包括其他模板)时,会导致在开发人员机器上生成大约5-10秒的目标文件。 。

据我所知,由于模板包含模型,VS编译器在编译模板方面也不是特别快(实际上,您在每个间接使用它的文件中都包含了模板的定义,并且每次修改时都可能重新实例化该模板)与模板无关的内容)(在进行增量编译时),编译时间可能会出现问题。

使用模板时,处理增量(且不仅是)编译时间的方法是什么(除了更好/更快的编译器:-)外)。


1
@RobertHarvey依赖项注入是使用模板参数进行的。在实例化这些代码的生产代码中,我的编译时间很慢。
Ghita 2012年


2
由于Andrei Alexandrescu撰写了“现代C ++设计”,许多C ++程序员认为他们必须对所有内容都使用模板,并让编译器尽可能多地进行处理。通常会导致您描述的那些效果。以前(现在仍然是使用其他语言的程序员),绝对不可以使用模板并通过运行时机制来处理诸如依赖注入之类的事情,即使最终用户需要更多的CPU周期(他几乎永远不会注意到) )。老实说,我确定罗伯特是100%正确的,那就是您对此的看法。
布朗

1
@Ghita:使用模板元编程的恕我直言,通常只是过早优化的一种形式(有时甚至是过大的杀伤力),但前提是您不会编写具有类似要求的STL库。您需要权衡一些性能增益才能获得更长的编译时间,更少的可维护性以及许多难以理解的错误消息。使用“外部模板”可能会在短期内为您提供帮助,但如果您愿意,我也会考虑长期的改进。
Doc Brown

4
@DocBrown。相反,您可以说避免模板以提高构建性能是过早的优化。模板是解决许多问题的理想抽象。
mike30 2012年

Answers:


9

如果模板参数只能假设一组有限(且很小)的值,则可以将其定义移至源文件中,并使用显式实例化

例如,aaa.h您仅声明模板函数fg

template <int n>
int f();

template <class T>
void g(int a);

假定n模板参数只能是1,3,6,和T模板参数只能是intlongvoid *

然后,您可以这样定义它们aaa.cpp

template <int n>
int f()
{
    ...
}

template <class T>
void g(int a)
{
    ...
}

template int f<1>();
template int f<3>();
template int f<6>();

template void g<int>(int a);
template void g<long>(int a);
template void g<void *>(int a);

这样,编译器将在编译时为给定参数实例化模板aaa.cpp。编译客户端代码时,它假定定义存在于某处,并且链接程序将进行处理。

#include "aaa.h"

int main()
{
    f<1>();
    f<3>();
    f<6>();

    g<int>(5);
    g<long>(5);
    g<void *>(5);
}

您也可以显式实例化模板类。缺点是您不能使用fg与其他模板参数一起使用。

#include "aaa.h"

int main()
{
    f<5>();
}

结果是

undefined reference to `int f<5>()'

我在一个项目中使用了此技术,在该项目中,很少有复杂的类依赖于小的(<10)整数模板参数集,并且显着减少了编译时间(因为编译器在编译客户端代码时不必解析复杂的模板定义)。 。当然,根据实际代码,您可能会得到较少的改进。


2

一旦我对类似的问题使用了一个奇怪的解决方案:包括STL导致每个源文件的编译时间大约为几秒钟-不管它有多小。因此,我将所有源文件都包含在一个主文件中,并且每个文件的编译时间几乎没有改变……这意味着速度提高了20倍以上,因为我只有一个文件可以编译。

为了保持设计整洁,我继续维护一个makefile,但从未实际使用过(除非确认它仍然有效)。


0

我们过去通常要完成一项繁重的任务,以在一夜之间构建我们的预编译头文件和预编译模板,然后在第二天才针对它们进行构建。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.