条件语句与函数指针的性能对比:哪种实现更快?
条件语句与函数指针的性能对比:哪种实现更快?
嘿,这个问题问到点子上了——咱们结合实际场景拆解分析,先把你给出的两种实现再清晰列出来:
第一种(循环内带条件判断):
while(running) { if(logMode == true) log(); bar(); }
第二种(提前绑定函数指针,循环内无判断):
if (logMode == true) func_ptr = log; else func_ptr = noop; //noop是啥也不做的空函数 while(running) { func_ptr(); bar(); }
接下来聊性能,核心得看**logMode的变化情况**和CPU的分支预测能力:
如果
logMode是全程固定不变的(比如程序启动后就再也不会切换这个标志):
现代CPU的分支预测器会很快学习到这个分支的走向,几乎能100%命中预测。这时候第一种写法的分支判断开销几乎可以忽略,甚至可能比第二种更快——因为函数指针调用涉及间接跳转,有额外的指令开销,而预测命中的分支基本没额外成本。如果
logMode可能中途变化,或者分支预测器没法稳定预测(比如标志偶尔切换):
这时候第一种写法的分支预测失败会导致CPU流水线清空,这可是个不小的性能惩罚!而第二种写法就没这个问题——循环里没有分支判断,每次都是直接调用提前绑定好的函数指针,不会触发分支预测失败的情况,性能优势就体现出来了。
另外还要提一句:空函数noop的实现要尽量简洁,比如写成一个只包含返回指令的函数,这样它的调用开销会非常小,不会拖第二种写法的后腿。
最后补充个小细节:如果logMode是编译期就能确定的常量,编译器会直接把第一种里的分支给优化掉,但你明确说不用条件宏,所以咱们默认是运行时动态判断logMode的场景。
备注:内容来源于stack exchange,提问作者Alex Mungan
相关产品推荐
相关产品推荐

