5

我对比较 ruby​​ 速度和 python 很感兴趣,所以我采用了最简单的递归计算,即打印斐波那契数列。

这是python代码

#!/usr/bin/python2.7                       
def fib(n):
    if n == 0: 
        return 0
    elif n == 1:
        return 1 
    else:
        return fib(n-1)+fib(n-2)

i = 0
while i < 35:
    print fib(i)
    i = i + 1

这是红宝石代码

#!/usr/bin/ruby

def fib(n)
    if n == 0
        return 0
    elsif n == 1
        return 1
    else
        fib(n-1)+fib(n-2)
    end
end 

i = 0 
while (i < 35)
    puts fib(i)
    i = i + 1 
end

在几次运行中,时间报告了这个平均值

real    0m4.782s 
user    0m4.763s 
sys     0m0.010s

那是红宝石,现在python2.7给出

real    0m11.605s
user    0m11.563s
sys     0m0.013s

这是怎么回事?

4

5 回答 5

8

python的递归效率是造成这种开销的原因。有关更多详细信息,请参阅本文。上述迭代解决这个问题的解决方案对于 python 来说更好,因为它们不会产生函数调用开销递归。我对 ruby​​ 的假设是它显然在优化代码,而 python 没有。同样,该文章使用几乎相同的 fib 函数对此进行了详细介绍。

于 2010-10-28T22:32:29.620 回答
2

所以对于这段代码,Python 比 Ruby 慢两倍多一点。可能对于其他代码,Python 会比 Ruby 更快。

您的 fib() 实现具有指数运行时间。这可以通过使用循环轻松避免。Python 示例:

a, b = 1, 1
for i in range(35):
    a, b = b, a+b
print b
于 2010-10-28T19:35:23.480 回答
2

您计算斐波那契数列中前 35 个数字的方法非常低效。你运行一个函数 fib() 35 次,每次 fib() 都有指数运行时间。Python 中的生成器是这个问题的完美解决方案,并且比您在 Ruby 中编写的要高效得多。

def fibo_generator(n):
    # gets Fibonacci numbers up to nth number using a generator
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

然后,您可以使用以下代码打印最多 35 的所有斐波那契数:

for f in fibo_generator(35):
    print f

这是迄今为止在 Python 中实现斐波那契序列的最有效方法,也是最通用的方法。

于 2010-10-28T19:49:04.250 回答
2

我对比较 ruby​​ 速度和 python 很感兴趣

微基准测试是比较语言的一种非常糟糕的方法,尤其是在你掌握这两种语言之前。如果你想要一个具有任何现实意义的基准,那么你需要付出很多努力——或者你在谷歌上搜索“语言枪战”

这是Python 和 Ruby的更好比较

于 2010-10-28T19:56:19.440 回答
2

这里还有一些要比较的数字:

Python2.7
9.67 用户 0.09 系统 0:09.78 经过 99%CPU (0avgtext+0avgdata 16560maxresident)k
0输入+0输出(0主要+1169次要)页面错误0交换

ruby 1.8.7 (2010-06-23 补丁级别 299) [x86_64-linux]
28.37 用户 0.35 系统 0:28.78 经过 99% CPU (0avgtext+0avgdata 9200maxresident)k
1896 输入 + 0 输出(9 主要 + 656 次要)页面错误 0 交换

ruby 1.9.2p0(2010-08-18 修订版 29036)[x86_64-linux]
6.21 用户 0.08 系统 0:06.36 经过 98% CPU (0avgtext+0avgdata 14160maxresident)k
4416 输入 + 0 输出(16 主要 + 953 次要)页面错误 0 交换

对于提供的代码,Python 比 ruby​​1.8快三倍,比 ruby​​1.9.1 慢 30%。

用于比较的其他 Python 版本:

2.4.6 耗时 10.30 秒

2.5.5 耗时 9.93 秒

2.6.6 耗时 9.22 秒

2.7 耗时 9.35 秒

3.0.1 耗时 11.67 秒

3.1.2 耗时 11.35 秒

3.2a3+ (py3k:85895, 2010 年 10 月 29 日, 01:41:57)
[GCC 4.4.5] 耗时 13.09 秒

2.5.2 (77963, 2010 年 10 月 15 日, 02:00:43)
[PyPy 1.3.0] 耗时 21.26 秒

2.5.1(Release_2_5_1:6813,2009 年 9 月 26 日,13:47:54)
[OpenJDK 64-Bit Server VM (Sun Microsystems Inc.)] 耗时 8.81 秒
于 2010-10-28T23:00:27.033 回答