2010-1-1

关于gcc对尾递归的优化,我做了这样一个实验:

#include <iostream> 
int sum(int n){ 
  return n<=1?1:sum(n-1)+n; 
} 
int main(int argc,char* argv[]){ 
  std::cout<<11<<std::endl; 
  std::cout<<sum(1000000)<<std::endl; 
  return 0; 
}

然后在Freebsd下
> uname -a
FreeBSD fb.localdomain 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:02:08 UTC 2009 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
gcc 4.4做测试
我故意把stacksize设置的比较小(20K)
#limit stacksize 20k
如果没有加-O2,那么编译完运行的时候会崩溃
#./hello
11
Segmentation fault (core dumped)
如果加了-O2 ,就不会
#./hello
11
1784293664

前几天我头儿在看简历的时候,说他很讨厌这样一种写法
for(Iterator i=v.begin();i!=v.end();++i){
....
}
假如这个循环体内部并未对这个容器进行任何的修改操作,那么v.end()应该提出 来。呃,我记得这个是effective C++上的某一条。
然后我想起这样一段代码:

char s[]="xxxxfsfxx"; 
for(int i=0;i!=strlen(s);++i){ 
  if(s[i]=='f'){ 
    //found it! 
    //do something 
    //then break 
    break; 
  } 
}

这个strlen也应该提出来。
这么做能提高代码的运行效率,但是会引入一个不必要的临时变量。
事实上编辑器的优化能力已经远远超出那些人的设想了。
首先,strlen可以被声明为__attribute__ ((pure))函数(或者更强一 点,__attribute__ ((const)))。编译器发现它并没有副作用,那么就会把它的执 行结果自动缓存下来。
其次,单就strlen本身而言,它往往是由编译器(例如gcc)来内置实现。于是可 优化的更多。
但这些仅仅是我的想象,我还没在vc9/gcc44上试过。vc对于这样的情况是如何处 理的?icc呢?solaris的cc呢?

此博客中的热门博文

在windows下使用llvm+clang

少写代码,多读别人写的代码

tensorflow distributed runtime初窥