Fab*_*ien 12 c++ templates c++11
这可能是一个简单的问题,我根本不掌握C++ 11模板.
我有一个通用的矢量类,不是std::vector<T>出于性能原因(非常具体的代码).
我观察到检查是否T是POD,如果是,执行特殊计算,效率要高得多:
void vec<T>::clear() {
if (!std::is_pod<T>::value) {
for (int i = 0; i < size; i++) {
data[i].~T();
}
}
size = 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我没有T为每个项目调用析构函数(size可能非常大)并且性能得到了提升.但是if (!std::is_pod<T>::value)一旦编译模板,测试就没用了:而不是编译成:
void vec<int>::clear() {
if (false) {
for (int i = 0; i < size; i++) {
data[i].~int();
}
}
size = 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望它被编译为:
void vec<int>::clear() {
size = 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器"聪明"是否足以跳过if (false)块或if (true)测试?我是否必须以不同的方式编写代码?
Kon*_*lph 26
编译器"聪明"是否足以跳过if(false)块或if(true)测试?
当然是.死代码消除是一种常规执行的简单优化.它的存在对于使许多调试库有效工作也很重要(=在发布模式下没有运行时开销).
但我可能仍然会重写这一点,以使读者可以看到这是一个编译时的区别,通过重载函数基于is_pod:
void vec<T>::do_clear(std::true_type) { }
void vec<T>::do_clear(std::false_type) {
for (int i = 0; i < size; i++) {
data[i].~T();
}
}
void vec<T>::clear() {
do_clear(std::is_trivially_destructible<T>());
size = 0;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我正在使用is_trivially_destructible而不是is_pod使代码更加不言自明,正如Nicol在评论中所建议的那样.该技术通常用于标准库实现和其他库中.它被称为标签调度.
And*_*zos 10
有一种称为伪析构函数的语言功能,专门为您想要做的事情而设计.基本上给出了一个类型模板参数T,你可以在语法上为它调用析构函数,如果在实例化时,T是一个标量类型(因为它是一个类似的基本类型int),它将编译并在其中生成一个no-op地点.
对于非标量的POD类型的其余部分,它们具有平凡的析构函数,因此同样会产生无操作.
即使是最低优化设置的任何生产编译器都会在无操作上省略循环.所以你可以安全地写:
void vec<T>::clear() {
for (int i = 0; i < size; i++) {
data[i].~T();
}
size = 0;
}
Run Code Online (Sandbox Code Playgroud)
基本上,您正在尝试解决编译器已经为您解决的假想性能问题.
| 归档时间: |
|
| 查看次数: |
675 次 |
| 最近记录: |