我们再查看 objc4
源码的时候,会看到苹果的大婶们常用的两个宏定义 fastpath
和 slowpath
我们来看看具体这两个定义是怎么样子的
1 |
大婶们写这个到底有什么意义呢?我们来看看这两个宏定义的意义
__builtin_expect(EXP, N)
这个指令是GCC
作用是允许程序员将最有可能执行的分支告诉编译器。 它的意思是EXP == N
的概率很大。
一般情况下,我们都是如何使用它的呢?
__builtin_expect(EXP, N)
的使用
既然我们知道了 __builtin_expect(EXP, N)
的作用,我们可以做一个假设。 比如我现在有个箱子,箱子里面有5个球,4个是蓝色的,1个是红色的。我们知道大概率下。我们随机抽取的球的颜色一定是蓝色的。这样我们就可以用这个指令,来减少指令跳转带来的性能下降
1 |
|
实际上,我们可以使用likely/unlikely宏来预测 x 的结果,然后通知编译器在编译时优化这个分支的汇编代码。
总结
__builtin_expect()
是 GCC (version >= 2.96)
提供给程序员使用的,目的是将“分支转移”的信息提供给编译器,这样编译器可以对代码进行优化,以减少指令跳转带来的性能下降。__builtin_expect((x),1)
表示 x 的值为真的可能性更大;__builtin_expect((x),0)
表示 x 的值为假的可能性更大。
也就是说,使用 likely()
,执行 if 后面的语句的机会更大,使用 unlikely()
,执行 else 后面的语句的机会更大。通过这种方式,编译器在编译过程中,会将可能性更大的代码紧跟着起面的代码,从而减少指令跳转带来的性能上的下降。
我们可以查看 __builtin_expect的使用这边文章,有更为详细的描述