为什么Python比Ruby更快?

14

它们似乎具有很多相同的特点,但据我所知,Python 2.5比1.8.7快得多。

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


3
为什么你选择1.8.7而不是稳定且推荐的1.9.1呢?1.9系列引入了YARV:http://en.wikipedia.org/wiki/YARV - Commander Keen
3
并不是想挑起争端什么的。只是想试试我系统里已经安装的Ruby 1.8.7。 - cduruk
4
我这里只是一名龟毛的人。其实语言并不会快或慢,影响速度的是解释器(也就是执行程序的工具)。你所说的是比较CPython解释器版本2.5和MRI解释器版本1.8.7的性能差异。如果比较Jruby和Jython、IronRuby和IronPython或Rubinius和PyPy等不同解释器,性能表现则可能截然不同。 - Noufal Ibrahim
6个回答

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官方发布的(每个“x”系列中最新的一个版本)。我没有2.3版本来检查,但我认为它应该比2.4版本慢一点。

这就是通过不断优化基本架构以实现连续发布的速度提升。虽然不像添加功能那样引人注目,但在现实世界中通常更加有用!-)

因此,我相信Ruby也可以稳定地运行在一个性能稳健的基础架构上,然后在未来的几年中得到持续的、界面下的性能优化,以获得(例如)我们在Python的至少某些部分中观察到的40%左右的进一步改进。


21

Python之所以更快,是因为它将代码编译成字节码,然后由高度优化的虚拟机执行。据我所知,Ruby在1.8及以前并不是这样工作的,而是实时解释AST树。

可以这样理解:

Python:

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

Ruby(1.9之前):

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

简单说一下,旧版Ruby中的第二步有很多重复操作,因为每次看到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一样。


实际上有非基于堆栈的虚拟机吗? - helpermethod
5
@辅助方法:Android上的Dalvik虚拟机,Lua自5.0版本起的虚拟机,tinypy Python虚拟机,tinyrb和RubyGoLightly Ruby虚拟机,以及正如@Eli Bendersky所提到的Parrot虚拟机是寄存器型虚拟机的几个示例。 - Jörg W Mittag
3
@Helper方法:哦,我怎么能忘记Nitro ECMAScript虚拟机呢,它是JavaScriptCore的一部分,因此也是OSX和Safari的一部分。 - Jörg W Mittag

6

因为Ruby 1.8在设计时并没有考虑性能问题,而Python更加优化。特别是,Ruby 1.8实际上是进行解释执行,而不像现今大多数语言一样编译成虚拟机代码。Ruby 1.9(使用YARV虚拟机)的速度与Python 3几乎相当(可能略慢一些,但非常接近),而其他实现甚至更快。


2
Ruby 1.9比Python慢2倍,1.8则慢4倍,请参见以下链接:https://dev59.com/XXA75IYBdhLWcg3wg5Zh - Nas Banov
1
@Nas Banov:这个问题并不是关于Alioth游戏性能的,因此将其作为“唯一”的答案是至少具有误导性的。对于一组高度专业化的基准测试(甚至称自己为“有缺陷”)而言,2倍是相当接近的。 - Chuck
1
我没有其他可靠的比较来源。与你或我单独相比,Language Shootout 肯定更可靠、更少偏见,因为有多个人参与 - 它是开放的,如果你认为某些代码对 Ruby 不公正,你可以修复它并改善结果...就像之前的人们一样 - 就像维基百科一样建立。 - Nas Banov
1
Nas Banov似乎并没有将基准测试游戏作为“标准答案”展示,而是将其视为比“我说它快大约一样快”的东西更加实质性的东西。 - igouy

4
我阅读了答案,看到大多数人都说“哦,你不应该与 Ruby 1.8 进行比较,你应该选择 1.9,它更快”。好吧,为什么不看一些基准测试呢?
以下是 Ruby 1.9(YARV)与 Ruby 1.8(MRI)的比较: http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=ruby 以下是 Ruby 1.9 与 Python 2.x 的比较: http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=python 总之,Ruby 1.9 大约比 Ruby 1.8 快 2 倍,但仍然比 Python 慢 2 倍。

PS. 我想在 Chuck 的反对之后澄清一下:我不认为 计算机语言对比 是关于 生命、宇宙和万物的终极答案。远非如此。我很乐意被引用其他客观来源。

我也很乐意听到 S/O 上的人们提供非正式/主观的结果,前提是他们参与了50次以上有关Python或Ruby的讨论,并且他们的Ruby/Python偏见在+/-5dB以内(Ruby/Python比率计算公式为RPR=10*log10(numTags('Ruby')/numTags('Python')) dB;因此对于用户Chuck,这将是10*log10(225/13)=12dB,我的为-10——我们都不能依赖于无偏见的意见):-)


这些基准测试很有趣,但你读入太多了。你的意思是“Ruby运行一些非常不寻常的程序,速度大约是Python的一半。” Alioth shootout游戏对于了解不同语言的特性很有用,但它们远远不能像“Ruby 1.9比Python慢2倍”这样给出精确的指示,就好像这是绝对真理,如果你使用它,你的程序就会看到这个结果。我相信Ruby 1.9仍然比Python慢,但仅仅依靠shootout游戏中相对较小的差异是一种有缺陷的方法。 - Chuck
@Chuck - "大约快2倍"和"大约慢2倍"似乎是Nas Banov以近似值的方式呈现的,而不是像你试图暗示的"精确指示"。 - igouy

0

越来越多的人已经从事Python开发多年,因此进行了更多的优化。这些语言同样灵活和表达力强,因此随着所有好的优化思路在两者中得到应用,它们的性能应该会趋于一致。正如上面所提到的,Ruby 1.9大大缩小了与Python之间的性能差距。


0

这取决于实现方式。Crystal 基本上是将 Ruby 编译成 C,甚至可以调用 C 库。然后你还有 Beam 端的 Elixir,别忘了 Java 和 C# 的对应物。但是没错,Ruby 这个事实标准确实比 Python 慢,也针对网站开发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接