阅读Android Frameworks中的C++代码时,经常会碰到在条件判断语句中使用了LIKELY和UNLIKELY这两个宏,找到这两个宏的定义如下:

view plain copy to clipboard print ?
  1. #defineLIKELY(exp)(__builtin_expect((exp)!=0,true))
  2. #defineUNLIKELY(exp)(__builtin_expect((exp)!=0,false))

long __builtin_expect (long exp, long c)是GCC的内建函数,解析如下:

你可以使用__builtin_expect给编译器提供分支预测的信息,通常,你因该明确使用这个编译选项(‘-fprofile- arcs’),因为很多程序员在如何预测他们编写的代码实际如何执行方面都很糟糕,使用这个宏可以很方面地让编译器优化分支跳转的代码。

这个函数的返回值就是exp:一个整形表达式,c必须是一个常量,该内建函数从语义上是表明:我们期望exp == c。

所以,如果你不考虑程序执行的效率,加不加LIKELY和UNLIKELY宏,执行的结果是一样的:

view plain copy to clipboard print ?
  1. if (LIKELY(exp))
  2. {
  3. }
  4. else
  5. {
  6. }

view plain copy to clipboard print ?
  1. if (exp)
  2. {
  3. }
  4. else
  5. {
  6. }

执行的结果是一样的。

那为什么还要使用这两个宏定义? 以汽车的速度为例子,如果速度超过200公里/小时表示有异常发生,代码可以这样写:

view plain copy to clipboard print ?
  1. if (speed>=200){
  2. //异常处理代码
  3. .....
  4. stop();
  5. }else {
  6. //正常处理代码
  7. continue ();
  8. }

也可以这样写:

view plain copy to clipboard print ?
  1. if (speed<200){
  2. //正常处理代码
  3. continue ();
  4. }else {
  5. //异常处理代码
  6. .....
  7. stop();
  8. }

这两个方案执行后都是正确的,但是显然效率是不一样的,因为大多数情况下,汽车的速度不会超过200公里/小时,当采用第一个方案时,大多数情况 下,代码执行到这里时CPU都要执行分支跳转的操作,这破坏了CPU的指令执行流水线,对性能的影响是显而易见的。而第二个方案则避免了这一问题,因为大 多数时候都是顺序执行的。

对于第一种方案,我们可以加上UNLIKELY宏来让编译器来优化:

view plain copy to clipboard print ?
  1. if (UNLIKELY(speed>=200)){
  2. //异常处理代码
  3. .....
  4. stop();
  5. }else {
  6. //正常处理代码
  7. continue ();
  8. }

加上UNLIKELY宏后,相当于告诉编译器:速度大于200是很少出现的。这样编译器在编译代码时,会适当地调整条件判断的方式,让CPU的指令 执行顺序尽可能不被打乱,已达到优化性能的效果。

所以,对于第二种方案,我们同样可以加上LIKELY宏:

view plain copy to clipboard print ?
  1. if (LIKELY(speed<200)){
  2. //正常处理代码
  3. continue ();
  4. }else {
  5. //异常处理代码
  6. .....
  7. stop();
  8. }

更多相关文章

  1. Android用代码实现EditText不可编辑
  2. Android中webview跟JAVASCRIPT中的交互
  3. Android(安卓)Lint gradle错误处理
  4. Android非Kotlin支持项目添加Kotlin代码时的注意点
  5. android 设置透明度 标题栏 窗体透明
  6. 利用androidannotations的@Rest注解替换Spring Android(安卓)Res
  7. Android(安卓)按键处理(驱动层到上层)架构
  8. Android消息处理机制
  9. Android与Java AIO实现简单Echo服务器与客户端

随机推荐

  1. 【android】GridView几个比较实用的属性
  2. Android PreferenceActivity介绍
  3. Android中程序与Service交互的方式
  4. Android Lottie动画的简单使用
  5. Android:快速修改ramdisk.img脚本
  6. Android 开发艺术探索笔记(十五) 之 Androi
  7. Win 10 下 android studio显示 Intel hax
  8. Android的异步任务AsyncTask
  9. Android中使用硬件加速的技巧
  10. Androidの解决自动旋转导致activity重启