为什么Python比Ruby更快?

cdu*_*ruk 12 ruby python performance programming-languages

它们似乎有很多相同的特性,但据我所知,Python 2.5比1.8.7快了很多.

这背后有更深层次的原因吗?

Ale*_*lli 24

没什么深刻的,我很确定 - 这完全是实施选择和成熟的问题.毕竟不久前,Python在许多方面都相当慢了!考虑例如:

$ py24 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 10.8 usec per loop
$ py25 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 9.83 usec per loop
$ py26 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 8.12 usec per loop
$ py27 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 6.35 usec per loop
Run Code Online (Sandbox Code Playgroud)

是的,所有在同一台机器上(的MacBook Pro,2.4 GHz的英特尔Core 2 Duo处理器,OSX 10.5),所有的"官方"苹果从python.org释放(最新的每一个x2.x系列).我没有2.3可以检查,但我希望它比2.4慢一点.

这只是在很多相同底层架构的连续版本中可以实现的许多热爱,艰苦工作的加速类型.不像添加feechurz那样华而不实,但在现实世界中通常更有用! - )

因此,我很确定Ruby还可以稳定在一个声音良好,性能稳健的底层架构上,然后开始在多年来获得稳定的底层性能调整以获得(例如)40%左右我们在这里观察到的进一步改进在过去几年中已经发生在Python的(至少某些部分).


Eli*_*sky 21

一个原因是Python被编译成字节码,然后由高度优化的VM执行.AFAIK Ruby在1.8及更早版本中不会以这种方式工作 - 但是可以动态地解释树.

想一想:

蟒蛇:

  1. 将代码解析为AST
  2. 将AST转换为字节码
  3. 在VM上运行字节码

Ruby(1.9之前):

  1. 将代码解析为AST
  2. 通过递归遍历直接解释AST

在没有太多细节的情况下,旧Ruby中的第2步有很多重复,因为它必须在每次看到它时"理解"AST(在内部循环中很多).Python只"理解"AST一次,然后VM尽可能快地运行字节码(原则上与Java和.NET VM的工作方式没有区别).

Ruby 1.9转移到了YARV,这也是一种基于VM的方法.Ruby 1.9比1.8快.以下是YARV创始人 Koichi Sasada 的一句话:

起初,YARV是运行伪顺序指令的简单堆栈机器.旧解释器(matzruby )天真地遍历抽象语法树(AST).显然它很慢.YARV将AST编译为YARV字节码并运行它.

值得注意的一点是,Python VM也是基于堆栈的,就像YARV一样.

  • @Helper方法:Android上的Dalvik VM,自5.0以来的Lua VM,小型Python VM,tinyrb和RubyGoLightly Ruby VM,以及@Eli Bendersky已经提到的Parrot VM只是基于寄存器的VM的几个例子. (5认同)
  • @Helper方法:哦,我怎么能忘记Nitro ECMAScript VM,它是JavaScriptCore的一部分,因此也是OSX和Safari的一部分. (3认同)
  • @Helper:当然.例如,Parrot是基于寄存器的 (2认同)

Chu*_*uck 6

因为Ruby 1.8并没有真正考虑到性能,而Python则更加优化.特别是,Ruby 1.8做了真正的解释,而不是像大多数语言一样编译虚拟机.Ruby 1.9(使用YARV VM)的速度与Python 3一样快(可能稍慢,但更接近),其他实现甚至更快.

  • Ruby 1.9比Python慢​​2倍,1.8慢4倍,见下文http://stackoverflow.com/questions/3252568#3262523 (2认同)