假设我要在命名空间l
中创建自己的库。使尽可能多的命名空间成员模板化是否有益?这将鼓励编译器只为库用户实际调用的成员生成指令。为了阐明我的观点,我将在此处进行演示:
1)
namespace l{
template <typename = void>
int f() { return 3; }
}
vs。
2)
namespace l{
int f() { return 3; }
}
主要是为了显示区别而没有被调用。
int main() { return EXIT_SUCCESS; }
功能1)不需要l::f()
的附加说明:
main:
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], 0
mov eax, 0
pop rbp
ret
功能2)确实需要l::f()
的附加说明(如果再次未调用l::f()
,则为该指令):
l::f()
push rbp
mov rbp, rsp
mov eax, 3
pop rbp
ret
main:
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], 0
mov eax, 0
pop rbp
ret
答案 0 :(得分:2)
tl; dr
使库函数模板化以避免编译器指令是否有益?
不。发出无效代码不是编译的昂贵部分。文件访问,解析和优化(不一定按此顺序)需要时间,并且这种想法迫使库客户端读取和解析比常规标头+库模型更多的代码。
通常将模板归咎于放慢构建,而不是加快构建速度。
这也意味着您无法提前构建库,因此每个用户都需要在使用它们的每个翻译单元中编译他们从头使用的任何部分。
使用模板版本的总编译时间可能会更长。您必须进行分析以确保(而且我怀疑此f
太小,以至于无法以任何一种方式衡量),但我很难将其视为有用的改进。
您的比较无论如何都不代表-好的编译器会在链接时丢弃死代码。有些还可以从静态库内联代码,因此对编译时或运行时性能没有可靠的影响。