编译器比你聪明


#42

下面说一下一些程序员间流传的一些 技巧, 以及和不使用这些技巧但是依赖编译器的优化, 结果有啥不同


#43

应该在帖子开头加个p.s 以下内容对msvc不一定成立. windows程序员珍重.


#44

这里是两个进行区间检查的代码

int regular(int i) {
   if (i>5 && i<100)
       return 1;
   exit(0);
}

int clever(int i) {
    return (((unsigned)i) - 6 > 93);
}

注意, 因为将有符号转为无符号整数, 导致负数会变得很大, 于是就可以少进行一次比较.

显然, 从直觉上来看, 上面的代码要进行两次比较, 而下面的代码只需进行一次比较. 当然, 为了 效率 要使用下面的编码.


#45

int clever(int i) {
return (((unsigned)i)} - 6 > 93); } =====> int clever(int i) {
return (((unsigned)i)) - 6 > 93); }


#46

这是用 gcc 编译优化的结果

结论是

  • gcc 也知道这个技巧!!! 这里很明显的看到, gcc 将两次比较优化成了一次! 用的就是上文提到的技巧!!!
  • gcc 甚至知道 exit(0) 是不会返回的, 所以没有为 call exit 下面插入弹栈指令.

#47

你知道的优化技巧编译器也知道, 你不知道的优化技巧, 编译器还是知道 !!


#48

只要你清楚的告诉编译器你的意图, 编译器就会利用它那庞大的知识库寻找到最合适的优化!


#49

我操!那我不是白干好多优化……


#50

看来以后在优化代码前,要检查编译器是不是可以自动优化。


#51

其实我想问一下,怎么知道编译器给我们做了哪些优化?


#52

看汇编代码呗

字数~~~ 字数


#53

通常来说, 编译器作者知道的优化技巧肯定比你多.


#54

有没有更给力的?下面没有了? —


#55

数学计算优化

看下面两个函数和对应的汇编指令

看到什么没有?


意思是 a/4 的时候无需写 a>>2, 编译器会优化为移位

编译器计算 a*9+17 的办法比任何一个人都要厉害! 只用了一条指令!


#56

这是必须的。但是开发者很难去设置编译器的优化参数,除了查手册,有什么更方便的方法能让小开发者更快的设置编译器参数?


#57

这个确实是,按拉运算是最快的。但是编译器自动把算术运算优化了。


#58

牛逼, niubility…


#59

在来一个几乎没人会知道的优化技巧, 编译器也知道

注意看汇编代码出现了 rep ; ret

这是一个在 某系列的 CPU 里出现的一个有关ret的性能问题, 编译器巧妙的使用 rep ret 将这个bug 给避开了 !

几乎没有多少人知道 !


#60

这个我喜欢!!我爱弄b = higher * 0x100 | lower这样的,之前有些人还批评我……


#61

java编译器也这么牛逼吗?如果java编译器太烂,手动优化也是有必要的