简体   繁体   English

这个python代码有什么问题,为什么它比ruby运行得那么慢?

[英]Is there something wrong with this python code, why does it run so slow compared to ruby?

I was interested in comparing ruby speed vs python so I took the simplest recursive calculation, namely print the fibonacci sequance. 我有兴趣比较ruby speed和python,所以我采用了最简单的递归计算,即打印fibonacci sequance。

This is the python code 这是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

and here is the ruby code 这是红宝石代码

#!/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

over several runs, time reports this average 在几次运行中,时间报告此平均值

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

thats for ruby, now python2.7 gives 多数民众赞成红宝石,现在python2.7给出

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

Whats the deal? 这是怎么回事?

The recursion efficiency of python is the cause of this overhead. python的递归效率是这种开销的原因。 See this article for much more detail. 有关更多详细信息,请参阅此文章 The above solutions that solve this iteratively are better for python since they do not incur the function call overhead recursion does. 上面解决这个迭代的解决方案对于python更好,因为它们不会引起函数调用开销递归。 My assumption about ruby would be that it is clearly optimizing the code while python is not. 我对ruby的假设是,它显然是优化代码而python不是。 Again, that article goes into a lot detail about this using a nearly identical fib function. 同样,该文章使用几乎相同的fib函数详细介绍了这一点。

So for this code, Python is a bit more than two times slower than Ruby. 所以对于这段代码,Python比Ruby快两倍多。 Probably for other codes, Python will be faster than Ruby. 可能对于其他代码,Python将比Ruby更快。

Your implementation of fib() has exponential run time. 您的fib()实现具有指数运行时。 This can easily be avoided by using a loop. 通过使用循环可以很容易地避免这种情况。 Python example: Python示例:

a, b = 1, 1
for i in range(35):
    a, b = b, a+b
print b

Your method of calculating the first 35 numbers in the fibonacci sequence is immensely inefficient. 你计算斐波纳契数列前35个数的方法非常低效。 You run a function fib() 35 times, and each time fib() has exponential run time. 你运行一个函数fib()35次,每次fib()都有指数运行时间。 The generator in Python is the perfect solution to this problem and is far more efficient than what you wrote in Ruby. 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

You can then print all fibonacci numbers up to 35 using this code: 然后,您可以使用以下代码打印最多35个斐波纳契数字:

for f in fibo_generator(35):
    print f

This is by far the most efficient way to implement the fibonacci sequence in Python as well as the most versatile. 这是迄今为止在Python中实现斐波纳契数列的最有效方法,也是最通用的方法。

I was interested in comparing ruby speed vs python 我有兴趣比较ruby speed和python

Microbenchmarks are a really bad way to compare languages, especially before you mastered both. 微量标记是比较语言的一种非常糟糕的方法,特别是在你掌握两者之前。 If you want a benchmark that has any real world meaning then you need to put a lot of effort into it - or you google for "language shootout" 如果你想要一个具有任何真实世界意义的基准,那么你需要付出很多努力 - 或者谷歌为“语言枪战”

Here is a better comparison of Python and Ruby 这是Python和Ruby的更好比较

Here's some more numbers to compare: 这里有一些比较的数字:

Python2.7
9.67 user 0.09 system 0:09.78 elapsed 99%CPU (0avgtext+0avgdata 16560maxresident)k
0inputs+0outputs (0major+1169minor)pagefaults 0swaps

ruby 1.8.7 (2010-06-23 patchlevel 299) [x86_64-linux]
28.37 user 0.35 system 0:28.78 elapsed 99% CPU (0avgtext+0avgdata 9200maxresident)k
1896inputs+0outputs (9major+656minor)pagefaults 0swaps

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
6.21 user 0.08 system 0:06.36 elapsed 98% CPU (0avgtext+0avgdata 14160maxresident)k
4416inputs+0outputs (16major+953minor)pagefaults 0swaps

Python is three times faster than ruby1.8 and 30% slower than ruby1.9.1 for the code provided. 对于提供的代码,Python比ruby1.8 三倍比ruby1.9.1慢30%。

Other Python versions for comparison: 其他Python版本用于比较:

2.4.6 took 10.30 seconds

2.5.5 took 9.93 seconds

2.6.6 took 9.22 seconds

2.7   took 9.35 seconds

3.0.1 took 11.67 seconds

3.1.2 took 11.35 seconds

3.2a3+ (py3k:85895, Oct 29 2010, 01:41:57) 
[GCC 4.4.5] took 13.09 seconds

2.5.2 (77963, Oct 15 2010, 02:00:43)
[PyPy 1.3.0] took 21.26 seconds

2.5.1 (Release_2_5_1:6813, Sep 26 2009, 13:47:54) 
[OpenJDK 64-Bit Server VM (Sun Microsystems Inc.)] took 8.81 seconds

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么Apache-Spark - Python在本地与熊猫相比如此之慢? - Why is Apache-Spark - Python so slow locally as compared to pandas? 与顺序版本相比,Python 中的慢并行代码,为什么它更慢? - slow parallel code in Python compared to sequential version, why is it slower? 与Java或C#中的相同算法相比,为什么在Python中这种主要筛子这么慢? - Why is this prime sieve so slow in Python compared with the same algorithm in Java or C#? 为什么 Python 和 Ruby 这么慢,而 Lisp 实现却很快? - Why are Python and Ruby so slow, while Lisp implementations are fast? 与“优化的”迭代素数搜索相比,为什么 Eratosthenes 的 Sieve 这么慢? (Python 3) - Why is Sieve of Eratosthenes so slow compared to “optimized” iterated prime search? (Python 3) 与某些 python 替代品相比,为什么 pandas.read_fwf function 这么慢? - Why is the pandas.read_fwf function so slow compared to some python alternatives? 为什么我的带有 if else 子句的 for 循环运行得这么慢? - Why does my for loop with if else clause run so slow? 为什么检查isinstance(某事,Mapping)这么慢? - Why is checking isinstance(something, Mapping) so slow? 为什么遍历 pytorch 张量如此缓慢(与 Numpy 相比)? - Why is looping through pytorch tensors so slow (compared to Numpy)? 为什么这个主要测试与另一个相比如此缓慢? - Why is this prime test so slow compared to this other one?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM