为什么Python比Ruby快?

14 投票
6 回答
10233 浏览
提问于 2025-04-16 01:19

它们看起来有很多相似的特点,但根据我的观察,Python 2.5的速度比1.8.7快很多。

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

6 个回答

6

因为Ruby 1.8在设计的时候并没有特别考虑性能,而Python则做得更优化。具体来说,Ruby 1.8是直接解释代码,而不是像现在大多数语言那样先把代码编译成虚拟机能理解的格式。Ruby 1.9(使用YARV虚拟机)和Python 3的速度差不多(可能稍微慢一点,但差距不大),而且还有其他版本的Ruby速度更快。

21

一个原因是,Python会先把代码编译成字节码,然后再由一个高度优化的虚拟机(VM)来执行。而据我所知,Ruby在1.8及之前的版本并不是这样工作的,它是实时解释代码的。

可以这样理解:

Python的处理流程:

  1. 把代码解析成抽象语法树(AST)
  2. 将AST转换成字节码
  3. 在虚拟机上运行字节码

Ruby(1.9之前的版本)的处理流程:

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

不深入细节来说,旧版Ruby的第二步有很多重复的过程,因为每次看到AST时,它都需要“理解”一次(而在内循环中,这个次数是非常多的)。而Python只需要“理解”一次AST,然后虚拟机就能尽可能快地运行字节码(这在原理上和Java和.NET的虚拟机工作方式是一样的)。

Ruby 1.9引入了YARV,这也是一种基于虚拟机的方法。Ruby 1.9比1.8快。以下是YARV的创造者佐佐田浩一的引用:

最初,YARV是一个简单的栈机器,运行伪顺序的指令。旧的解释器(matzruby)遍历抽象语法树(AST)时非常简单,显然速度很慢。YARV将AST编译成YARV字节码并运行。

有趣的是,Python的虚拟机也是基于栈的,和YARV一样。

26

其实没什么特别深奥的,我很确定这只是实现选择和成熟度的问题。毕竟,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

没错,都是在同一台机器上(Macbook Pro,2.4 GHz Intel Core 2 Duo,OSX 10.5),都是从python.org下载的“官方”Mac版本(每个x2.x系列中的最新版本)。我没有2.3版本来检查,但我觉得它可能会比2.4稍微慢一点。

这就是通过大量的努力和细致的工作,在几乎相同的基础架构上实现的速度提升。虽然这不如添加新功能那么引人注目,但在现实世界中往往更有用!-)

所以我很确定,Ruby也可以在一个稳定、性能强大的基础架构上发展,然后随着时间的推移,逐渐进行一些性能优化,就像我们在过去几年中看到的Python在某些方面大约提升了40%那样。

撰写回答