本文作者在开发Dynym项目,这是一个动态语言的通用运行时。在开发时,作者以其他语言的运行速度作为基础比较语言的
运行速度,因此发现了一些小秘密。迭代计算斐波那契数列是测试各种语言执行速度的常见方法。作者以不同的语言进行测试,最终发现C语言要比Python编
写的计算斐波那契数列快278.5倍。在底层开发,以及专注性能的应用程序中,选择是显而易见的。而为什么会有如此大的运行性能差距呢。作者进一步研究了
程序的反汇编代码,发现差别出在内存的访问次数,以及预测的CPU指令的正确性方面。(感谢 乾龙_ICT 的热心翻译。如果其他朋友也有不错的原创或译文,可以尝试提交到伯乐在线。)以下是译文。
原作者注:在本文最开始,我并没说明进行模2^64的计算——我当然明白那些不是“正确的”斐波那契数列,其实我不是想分析大数,我只是想探寻编译器产生的代码和计算机体系结构而已。 最近,我一直在开发Dynvm——一个通用的动态语言运行时。就像其他任何好的语言运行时项目一样,开发是由基准测试程 序驱动的。因此,我一直在用基准测试程序测试各种由不同语言编写的算法,以此对其典型的运行速度有一个感觉上的认识。一个经典的测试就是迭代计算斐波那契 数列。为简单起见,我以2^64为模,用两种语言编写实现了该算法。 用Python语言实现如下:
用C语言实现如下:
用其他语言实现的代码示例,我已放在github上。 Dynvm包含一个基准测试程序框架,该框架可以允许在不同语言之间对比运行速度。在一台Intel i7-3840QM(调频到1.2 GHz)机器上,当 n=1,000,000 时,对比结果如下:
很明显,C语言是这里的老大,但是java的结果有点误导性,因为大部分的时间是由JIT编译器启动(~120ms)占用的。当n=100,000,000时,结果变得更明朗:
在这里,我们探究下为什么C语言在2013年仍然很重要,以及为什么编程世界不会完全“跳槽”到Python或者 V8/Node。有时你需要原始性能,但是动态语言仍在这方面艰难挣扎着,即使对以上很简单的例子而言。我个人相信这种情况会克服掉,通过几个项目我们能 在这方面看到很大的希望:JVM、V8、PyPy、LuaJIT等等,但在2013年我们还没有到达“目的地”。 然而,我们无法回避这样的问题:为什么差距如此之大?在C语言和Python之间有278.5倍的性能差距!最不可思议的地方是,从语法角度讲,以上例子中的C语言和Python内部循环基本上一模一样。 |