现在的位置: 首页 > 综合 > 正文

编译器细节考虑

2013年11月14日 ⁄ 综合 ⁄ 共 2379字 ⁄ 字号 评论关闭

今天自己实现了一个堆排序,分别用VC2008,GCC4.3.2(MinGW),和C#3.0实现了一边。然后自己试着看这3个环境下的效率如何,且看各家表现:
10w数量级的堆排序
VC2008(Release)——33ms
VC2008(Debug)——(1690ms 加/RTC1)(221ms 不加/RTC1 )
GCC4.3.2(Release)——15ms
GCC4.3.2(Debug in GDB 6.8)-120ms
C#3.0(Release)——331ms
C#3.0(Debug)——340ms
      本着科学的精神,我应该每个类型测试10次,然后取平均数,但是以上数据只是在测试1~2次后,我取的大概值,所以还是难以保证公众。但是仅仅从数量级上面来讲还是有一点说头的。
      另外关于Debug下的性能考虑似乎有点多余,或者钻牛角尖,权且当做如此。
下面具体说下我的试验环境:
VC2008篇
VC的编译选项:
/O2 /Oi /Ot /D "_MBCS" /FD /EHsc /MD /Gy /Fo"Release//" /Fd"Release/vc90.pdb" /W3 /nologo /c /Z7 /TP /errorReport:prompt(Debug版本的改变相应地方,这里不再重复)
       VC是开了编译优化的,但是无论我怎么设置,其Release版本的事件变化不大。
Debug下面可就大大的不同了!上面列出来的数据实在是给VC丢脸了,竟然高着2个数量级。这里是加了一个小小的选项/RTC1 ,关于这个选项是做什么的我们后面再说。在Debug下面优化选项会全部失效。我选择的调试选项是/ZI(用于“编辑并继续”的程序数据库)。
看来这个/RTC1很有来头,竟然会引起这么大的差异!
/RTC1的来头:
  /RTC1隶属与VC的基本运行时检查,基本运行时检查一个有如下的几个选择:
/RTC1 =/RTCcu
/RTCc  当向较小的数据类型赋值从而导致数据丢失时报告。
/RTCs  启用堆栈帧运行时错误检查。这个还是很有用的!面向悬空指针,未初始化等问题。
/RTCu  当使用尚未初始化的变量时报告。
MSDN上面的说明是这样的:
对于开发版本,应该使用 /RTC;对于零售版本,不应该使用 /RTC。/RTC 不能与编译器
优化 ) 一起使用。与用 /Od 生成的映像相比,用 /RTC 生成的程序映像稍大一些,
速度也稍慢一些(最多比 /Od 版本慢 5%)。
看来Microsoft又再忽悠人了,何止是慢5%,是慢了5000%,虽然这个问题是一个概率的
问题,但是也不能相差如此!
 
GCC4.3.2篇
不管是发行版本还是调试版本,GCC都全面战胜了VC2008,实在是难能可贵。
刨除我代码垃圾的因素,且看两家STL的表现:

GCC:sort(快排)——1ms~2ms

VC2008:sort——2ms~3ms

GCC:stable_sort(归并排序)——3ms~4ms

VC2008:stable_sort——6ms~8ms

Mircosoft实在是太丢人了,改天download下Intel Compiler试试三家大战的结果!网上一直

流传VC编译器的美名,看来也是相对的......

我的GCC的编译全新如下:
 g++-dw2.exe    -c -O2 -MMD -MP -MF build/Release/MinGW_TDM-Windows/newmain.o.d -o build/Release/MinGW_TDM-Windows/newmain.o newmain.cpp
这个是Release版本的,Debug的不再列出。
优化选项开到了O2,具体开到O3估计结果变化不大,具体GCC的编译优化选项的说明请看:
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Optimize-Options.html
注意到GNU如是说:
Turning on optimization flags makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program.
打开优化选项会使编译器试图改进程序性能或/且减小程序大小(编译后的二进制文件),但是这是以牺牲编译时间与调试性能为代价的。
看来Debug下的GCC也是有时间代价的,当然这些情况是难免的。另外关于GCC优化选项实在是很有的说,他比VC提供了更高的灵活度,几乎设计到了各个方面,面对一堆E文,我也没有仔细的读每个选项。

C#3.0
完全合乎情理之中,托管环境就是慢,很正常,这个是编程便捷的代价,软件开发世界向来是如此的平衡,你在某个地方的取得是以另一个地方的付出为代价的,这里不多说。
      另外当我把我的C++代码翻译到C#的时候(我是先实现了C++),发现C#的泛型与C++的模板类的差别还是很大的,比如C#的泛型约束机制,C#的泛型大概是2.0的时候才引进的,在这些方面和Java比较相像,Java也是有泛型约束的,这个是为了保障代码的健壮性,C#与Java都是一门不灵活的语言,Microsoft和Sun都试图把他们的一些理念(通常都是好的理念)强加给你,比如如果在C++里面的一模板类,C++是不对其做任何检查的,这样可能引起一些显著的问题,比如你的模板类用到了if(T1>T2)这里的T1、T2都是T的对象,那么这个模板类就要保证T重载了>操作符,这个“保证”只能又模板类的使用者提供,而C#下面你的类可以这么声明:class A<T> where T:IComparable这样,这个“保证”是又泛型编写者强加给使用者的,这样可以保证代码的健壮性,应了那句台词:源代码就是设计。

抱歉!评论已关闭.