优化C++/GCC模板编译时间

17
在一个大项目中,我们有很多类(数千个),并且为每个类定义了一个特殊的智能指针类型,使用typedef。这个智能指针类型是一个模板类。当我使用"gcc -Q"编译时,我看到gcc花费了大量时间来为每个类编译这些智能指针,即我看到smartptr<class1>::methods, then smartptr<class2>::methods... smartptr<class2000>::methods在屏幕上滚动,因为gcc在处理它们。
有没有什么诀窍可以加快这个过程?从smartptr的角度来看,这些类都是相同的,没有启用任何enable_if技巧等。
我现在正在尝试的事情:
- 可能会创建一个具有少量公共方法的非模板基类 - 使用extern template class来减少链接符号(和实例化时间?还不确定)
但以上所有内容都不是完整的解决方案。我想知道是否有另一种优化编译时间的方法,一种诀窍可以让gcc知道,例如如果它解析了smartptr一次,那么当看到其他专业化时,它可以反复应用相同的知识,因为生成的代码是相同的。
是的,我知道它不完全相同......但那只是个疯狂的想法。
或者也许还有其他我不知道的技巧,可以加快编译速度。(只是为了给你一个想法,我们可以通过消除其静态成员数据实例化来优化另一个模板,这大大减少了编译时间。这一点并不明显。)

4
这个有用吗?https://dev59.com/uWw05IYBdhLWcg3wiyRJ - brian beuning
还不太确定,但它肯定值得点赞。 - queen3
1
我记得std vector曾经为T*重用void 实现--基本上,强制转换是T所需做的全部。这个技巧可能值得探索。 - Yakk - Adam Nevraumont
根据您的指针的智能程度和兼容性,#define smartptr std::shared_ptr 可以提供帮助。内联方法可以减少链接/实例化时间。 - Olaf Dietsche
Addref不需要删除,可以作为一个例子。因此可以将其分解出来... - Yakk - Adam Nevraumont
显示剩余5条评论
2个回答

1

虽然不是具体针对GCC,但我认为从非模板基类派生smartptr的想法听起来很可靠。智能指针是这种方法的一个好候选,因为重复生成的大部分代码并不关心指针是否为void*。(我会尽可能将代码转移到类模板中,以便仅在必要时进行void*的强制转换。)

此外,如果有成千上万个类严重依赖smartptr,则应首先考虑通过这种方式解决问题。仅当该方法失败时,我才会转向smartptr的客户端代码(此时,值得考虑避免通用头文件膨胀的技术)。

至于extern template declarations,我没有相关经验,但听起来您需要每个typedef添加一个extern声明。值得注意的是,强制完整实例化的相反效果是这样实现的:

template class smartptr<MyClass>;

我会仔细检查一下这行代码是否与你的任何typedef相关联!


0

预编译头文件

如果您的代码更改不在头文件中,这实际上可能有助于减少编译时间。 (源代码)


可能不是一个很明智的答案,因为模板只存在于头文件中,所以对模板的任何更改都会破坏PCH。而且对于模板,人们希望优化C++文件的慢速构建,这是由于模板实例化所导致的。同样,PCH在这里并没有帮助(它可以节省一些解析模板的时间,但不能节省实例化的时间,这似乎是瓶颈所在)。因此,正确的方法是优化模板代码本身,特别是如果模板被实例化多次或者如果它们是递归的(在编译时计算某些东西/处理类型列表)。 - the swine
这实际上是一个复杂的问题,因为它取决于编译器的具体情况(最可能的是模板成员函数在调用时被实例化)。因此,如果你假设模板在头文件中使用,则是的。另一方面,除非是另一个模板的代码,否则你不应该把任何代码放在头文件中(除了声明和内联函数)。因此,在遵循这种约定的代码中,答案是否定的。 - the swine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接