避免启用RTTI机制
【说明】 采用C++语言开发性能敏感项目,可以考虑从编译器层面关闭RTTI机制,避免由此带来的开销;实践方面,如果采用gcc编译器,可以采用“-fno-rtti”关闭RTTI机制。
【原理】 RTTI机制是运行阶段类型识别(Runtime Type Identification)的简称,是C++中的特性之一,具体地,可以通过typeid、typeinfo、和dynamiccast等运算符,实现运行阶段的对象类型识别,并以此做出相应的业务处理。 在启用RTTI机制后,可能带来如下问题:
- RTTI带来了额外的内存和运行效率开销,由于RTTI机制需要在编译阶段保存与生成更多的类型信息(如类型名等),可能带来代码段的开销,在运行时,执行typeid/dynamic_cast等运算符时,其中可能存在递归检测(如多重继承场景)过程,在性能敏感流程中可能带来明显的恶化。
- 由于RTTI机制在不同编译器下的支持程度以及实现方式可能存在差异,启用RTTI也可能会带来兼容性风险。
【注意事项】 RTTI作为C++的语言特性,其运行期类型识别对于安全性有一定的补充,与此同时,其也会带来性能开销,因此需做好语言特性的选型。
RTTI机制会带来一定的性能损耗,项目中应该根据实际情况选择,编码中可以设计合理的多态来替代RTTI;运行时确定对象类型,在泛型编程、一些设计模式(例如:阅后即焚)中经常用到,所以要根据实际情况在效率损失和其他收益上做好权衡。
【案例】
优化前:
// input.cpp
class BaseClass {
...
};
class DerivedClass : public BaseClass {
...
};
void TestFunc()
{
BaseClass *derived = static_cast<BaseClass *>(new DerivedClass());
DerivedClass *temp = dynamic_cast<DerivedClass *>(derived);
...
delete derived;
}
g++ input.cpp -o output -Wall
说明: 上述编译命令将input.cpp编译成output可执行程序。按照默认选项配置,未禁用RTTI机制。
优化后:
g++ input.cpp -o output -Wall -fno-rtti
// 优化后的编译命令,将RTTI机制禁用,因此input.cpp无法编译通过
...\input.cpp: In function 'void TestFunc()':
...\input.cpp:30:62: error: 'dynamic_cast' not permitted with -fno-rtti
DerivedClass *temp = dynamic_cast<DerivedClass *>(derived);
父主题: C++语言