性能敏感路径上,优先采用inline函数或宏等方式替代简短的函数
【说明】 inline指定符的目的是提示编译器做优化,编译器可以基于其优化的目的,决定是否进行内联优化:对于函数体较小(如6LOC以内)且调用次数非常多的函数,可以将函数定义成inline函数。
关键字inline需与函数定义放在一起,且正确配置编译选项,才能使函数成为内联函数,仅仅将inline放在函数声明前(而不是在函数定义前),可能会导致编译错误(针对不同编译器,其表现可能存在差异,例如gcc编译器下inline修饰的函数,如果进行跨编译单元调用,则不进行内联展开,此场景下,inline函数与一般函数无异)。
如果由于项目的编译选项限制,无法实施inline,则可以考虑采用宏定义的方式优化。
【原理】 函数调用的过程存在入栈/出栈等开销,如果被调用函数距离当前函数较远可能未被加载到I-Cache中,存在加载指令的开销,采用inline方式定义的函数或采用宏定义的方式在编译时直接替换为函数体而避免函数调用、I-Cache miss、以及冗余参数校验带来的额外开销。
【注意事项】 采用内联方式,可能会增加BIN空间和代码段的消耗,需要在性能和空间之间做出平衡;可能导致软件调试定位难度增大、热补丁复杂度增大或不可行等问题,需要在性能和可维护性之间做出平衡。
【案例】
如下性能敏感流程中的函数,其作用是获取当前实例上下文,通过内联提升性能:
static inline void *Func(TransContext *transContext)
{
return GetContext(transContext->transType, transContext->contextIdx);
}
父主题: 函数设计