All Fast All Furious

来源:互联网 发布:苏宁app网络失败 编辑:程序博客网 时间:2024/04/29 07:50
  OSNews上Christopher W. Cowell-Shah的“终极”比较:Nine Language Performance Round-up: Benchmarking Math & File I/O
        考虑到偶已经搞出Fast and Furious和2 Fast 2 Furious,这篇文章没法不叫All Fast All Furious。

        这是个小规模的基准测试,涉及9种现代语言或其变种:Java 1.3.1, Java 1.4.2,使用gcc 3.3.1编译的C,Python 2.3.2,使用Psyco 1.1.1编译的Python,四种Visual Studio .NET 2003支持的语言:Visual Basic, Visual C#, Visual C++ 和 Visual J#。
        这个Benchmark使用了各种数据类型测试数学和三角函数,简单的文件I/O。所有测试都在运行Windows XP的Pentium 4机器上完成。
       
        促使Christopher做这个测试的愿意有5个:
       
        第一,他很好奇Java 1.4.2--最新的官方Java发布版--和Microsoft的 .NET 2003 系列语言谁的性能更好。Java和 .NET 语言都是semi-compiled或者说semi-interpreted的。源码都被编译成中间代码,然后与解释器或者JIT编译器一同运行。对Java来说,中间代码就是字节码,解释器/编译器就是Java虚拟机JVM;.NET世界里的源码被编译成Microsoft中间语言MSIL,运行在.NET公共语言运行时引擎上。
        除了拥有令Java广受欢迎的特性比如自动资源管理,垃圾收集和类型安全外,.NET还有些新特性,比如跨语言调试,简易的GUI设计和极为直白的应用部署方法。不过,这些特性会带来性能损失吗?在对其编程模式增加了复杂的层次结构后,Microsoft是否放弃了其对Java的速度优势?
        Christopher的想法是,Microsoft提供的J#是一个Java 1.1.4规范的Java实现,似乎可以用这玩意来和Java比照,结果应该可以反映出SUN和Microsoft的运行时系统开销。
       
        第二,Microsoft宣称同样的例程,用任何一种.NET语言编写然后编译到相同的MSIL后,最终能以相同的速度运行--这个说法确实很诱人,Christopher当然想检验一下。这个基准测试的代码相当简单,这么做才能保证各种.NET语言编写的例程在功能上是同等的。这四种语言是不是真的速度相同呢?
       
        第三,想看看Java或者.NET到底比完全编译的C慢多少。Christopher开始尝试了把CLR从Visual C++ benchmark中剥离出来--用#pragma unmanaged预处理指令关闭托管特性,不过没有成功,性能未见任何改善。之后Christopher把VC程序用gcc重新编译,以便让C能真正的享受本地代码,不托管,不依赖CLR的好处。
       
        第四,看看semi-compiled语言和完全解释语言的差别,后者的代表是Python,Perl和PHP。现在有种观点是随着硬件速度越来越快,价格越来越便宜,我们会发现编译型语言的速度优势会大大无用。
       
        最后,Christopher想看看Java前后不同版本之间的差别--这坏小子。SUN关于1.4.2性能提升的大牛皮早就吹出来了,所以咱们这次也测测Java 1.3.1到底和1.4.2差别有多大。
       
        设计良好的测试案例简直是fiendishly difficult。Christopher只测试了数学运算(32位整数算术运算,64位整数算术,64位浮点算术,64位三角运算),之后是顺序访问的文件I/O。测试并不复杂,没有涉及字符串处理,图形,对象创建与管理(对面向对象语言),复杂数据结构,网络访问,数据库访问。测试虽简单,不过能给出各种语言效率到底如何的大致印象。
       
        32位整数运算:
        使用32位循环计数器和32位整数操作数,循环从1到100万。忽略余数。
        1 - 1 + 2 * 3 / 4 - 5 + 6 * 7 / 8 - ... - 999,999,997 + 999,999,998 * 999,999,999 / 1,000,000,000
       
        64位整数运算:
        算法同上,换为使用64位循环计数器和操作数。循环从100亿到110亿。
       
        64位浮点算术:
        和64位整数算术算法相同,不过使用64位浮点循环计数器和操作数,不忽略余数。
       
        64位浮点三角函数:
        使用64位浮点循环计数器,计算从1到1千万的所有值的sin,cos,tg,基于10的对数和平方根。
       
        I/O:
        写100万行80个字符的数据到文本文件,然后读回内存。
       
        编译及优化等选项:
        Java 1.3.1:javac -g:none -O编译,java -hotspot 运行。
        Java 1.4.2:javac -g:none 编译,java -server 运行。
        C:gcc -march=pentium4 -msse2 -mfpmath=sse -O3 -s -mno-cygwin 编译。
        Python with and without Psyco:无优化。python -O只能加快加载,对运行无用。
        Visual Basic:使用Release配置,大开optimized,关闭integer overflow checks。
        Visual C#:release,打开optimize code。
        Visual C++:release,打开whole program optimization,优化为maximize speed,打开global optimizations,enable intrinsic functions,设置size or speed为favor fast code,设置omit frame pointers为yes,设置optimize for processor为Pentium 4 and above,设置buffer security check为no,设置enable enhanced instruction set为SIMD2,设置optimize for Windows98为no。
        Visual J#:release,打开optimize code,关闭generate debugging information。
       
        这里是测试代码。Java 1.3.1, Java 1.4.2 和 Visual J#使用的是相同代码。Visual C++ 和 gcc C使用几乎相同代码。C程序在Cygwin下用gcc编译。Psyco:增加import psyco 和 psyco.full()到Python代码头部。四个Microsoft语言的测试在Microsoft Visual Studio .NET 2003下完成。
        Java的log() 函数使用e为底算自然对数,其他语言都用10为底算对数。很奇怪Java没有基于10的log函数,这可能会影响性能。
       
        执行每个测试前,Christopher都整理了硬盘,重启机器,并关闭了不需要的后台服务。每个测试都运行了至少3遍,选用了最好结果。启动时间未计算在内。测试的硬件环境是:
        Type: Dell Latitude C640 Notebook
        CPU: Pentium 4-M 2GHz
        RAM: 768MB
        Hard Disk: IBM Travelstar 20GB/4500RPM
        Video: Radeon Mobility 7500/32MB
        OS: Windows XP Pro SP 1
        File System: NTFS
       
        结果:
        Python/Psyco 结果剔除在外--因为数字太大^_^
        单位:秒
        数值越小越优秀。
        
          int
math
long
math
double
math

trig

I/O

TOTAL
Visual C++ 9.6 18.8 6.4 3.5 10.5 48.8 Visual C# 9.7 23.9 17.7 4.1 9.9 65.3 gcc C 9.8 28.8 9.5 14.9 10.0 73.0 Visual Basic 9.8 23.7 17.7 4.1 30.7 85.9 Visual J# 9.6 23.9 17.5 4.2 35.1 90.4 Java 1.3.1 14.5 29.6 19.0 22.1 12.3 97.6 Java 1.4.2 9.3 20.2 6.5 57.1 10.1 103.1 Python/Psyco 29.7 615.4 100.4 13.1 10.5 769.1 Python 322.4 891.9 405.7 47.1 11.9 1679.0
        点击产看全尺寸图表

        
        分析:
        第一,Java(至少1.4.2的Java)和.NET 2003系列语言比,在大多数测试中表现都很不错。除了三角计算,Java事实上和VC--Microsoft最快的语言--一样快。不过Java的三角也太差了,连解释执行的Python都不如。让人迷惑的是1.3.1的三角表现不错。
        第二,Microsoft声称的所有的4种.NET语言都编译成MSIL似乎确有其事--至少对数学函数。整数算术运算的结果4种语言几乎相同。长整数,双精度和三角结果:VC#,VB和VJ#相同,不过C++编译器输出了令人印象深刻的快速代码。可能C++能更好地利用Pentium 4的SSE2 SIMD扩展完成算术和三角运算--仅是猜测。I/O测试两极分化,Visual Basic 和 Visual J#显然在利用I/O例程上效率比VC#和VC低。很明显,功能相同的代码并没有编译成相同的MSIL代码。
        第三,Java 1.4.2和gcc C一样优秀乃至更好--除了三角计算外。这是这次测试里最让人吃惊的地方。通常合乎大家逻辑的猜测是在JVM中运行字节码会带来某种性能损失--和本地机器码比较。在这次测试中,这个推测显然不知为什么不成立。
        第四,全解释执行的Python,和推测的一样,比任何全编译或半编译的语言都慢很多--又是甚至有1/60的差距。不过I/O性能上,Python和最快的语言也属于同一阵营,而且比VB和VJ#快。Psyco编译器能为Python创造奇迹,为数学和三角计算减少了10%到70%的时间--和未经Psyco编译的Python比。和把Psyco 包含到Python中的简单相比,这个性能提升是多么惊人啊。
        第五,Java 1.4.2比Java 1.3.1在算术上快很多。不过,前面提过,三角运算则落后了。 Christopher 猜测1.4.2中应该还有不同的,更有效地调用三角函数的方法。还有一种可能是1.4.2更注意精确而不是速度,所以新函数更准确但是速度更慢。
       
        收获是,Christopher很吃惊地发现:4个.NET 2003语言在许多测试上性能表现相近;Java 1.4.2 表现如此优异。Christopher的个人意见省去哈......
       
        这个测试还可以扩展到更广的范围,自己去OSNews瞧瞧吧。

        追求更高更快更强是支撑我们这种行业的精神,真的,没有这种冲劲,很多事情都会失去意义。

    
原创粉丝点击