使库函数模板化以避免编译器指令是否有益?

Is it beneficial to make library functions templated to avoid compiler instructions?

本文关键字:是否 指令 编译器 函数模板      更新时间:2023-10-16

假设我正在命名空间l中创建自己的库。使尽可能多的命名空间成员模板化是否有益?这将鼓励编译器仅为库用户实际调用的成员生成指令。为了明确我的观点,我将在这里演示它:

1)

namespace l{
template <typename = void>
int f() { return 3; }
}

与。

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

tl;博士

使库函数模板化以避免编译器指令是否有益?

不。发出死代码并不是编译的昂贵部分。文件访问,解析和优化(不一定按此顺序)需要时间,这个想法迫使库客户端读取和解析比常规标头+库模型更多的代码。

模板通常被指责为减慢构建速度,而不是加快构建速度。


这也意味着您无法提前构建库,因此每个用户都需要在使用它们的每个翻译单元中从头开始编译他们使用的任何部分。

使用模板化版本,编译所花费的总时间可能会更长。您必须分析才能确定(我怀疑这个f太小了,以至于无论哪种方式都是无法估量的),但我很难将其视为有用的改进。

无论如何,您的比较并不具有代表性 - 一个好的编译器会在链接时丢弃死代码。有些还可以从静态库中内联代码,因此对编译时或运行时性能没有可靠影响。