代码之家  ›  专栏  ›  技术社区  ›  rapadura

为什么python比Ruby慢,即使使用这个非常简单的“测试”?

  •  2
  • rapadura  · 技术社区  · 14 年前

    Is there something wrong with this python code, why does it run so slow compared to ruby? 我之前试图理解python和ruby之间的区别。

    正如igouy所指出的,我认为python速度较慢的原因可能与递归函数调用(涉及堆栈)不同。

    #!/usr/bin/python2.7
    i = 0
    a = 0
    while i < 6553500:
        i += 1
        if i != 6553500:
           a = i 
        else:
            print "o" 
    print a 
    

    在红宝石里是

    #!/usr/bin/ruby
    i = 0
    a = 0
    while i < 6553500
        i += 1
        if i != 6553500
           a = i 
        else
            print "o"
        end
    end   
    print a
    

    巨蟒3.1.2(r312:791472010年10月4日,12:45:09)

    时间python pytest.py o型

    6553499个

    实际0m3.637s

    ruby 1.9.2p0(2010-08-18版本29036)[x86_64-linux] 时间红宝石rutest.rb

    奥6553499

    实0m0.618s

    用户0m0.610s

    它运行在Intel(R)Core(TM)i7 CPU M 620@2.67GHz上,内存为4GB。

    为什么会这样?

    4 回复  |  直到 8 年前
        1
  •  16
  •   Glenn Maynard    14 年前

    首先,请注意您显示的Python版本不正确:这段代码是在Python 2.7中运行的,而不是在3.1中运行的(它甚至不是有效的Python3代码)。(仅供参考,Python 3通常比2慢。)

    也就是说,在Python测试中有一个关键问题:您将它作为全局代码编写。你需要把它写成一个函数。在Python 2和Python 3中,如果正确编写,它的运行速度大约是后者的两倍:

    def main():
        i = 0
        a = 0
        while i < 6553500:
            i += 1
            if i != 6553500:
               a = i
            else:
                print("o")
        print(a)
    
    if __name__ == "__main__":
        main()
    

    全局编写代码时,没有局部变量;所有变量都是全局变量。在Python中,局部变量比全局变量快得多,因为全局变量存储在 dict . VM可以通过索引直接引用局部变量,因此不需要哈希表查找。

    另外,请注意,这是一个非常简单的测试,您真正要做的是对一些任意字节码操作进行基准测试。

        2
  •  2
  •   lotrpy    14 年前

    为什么会这样?

    但赛顿成了救世主
    下面的纯python版本借用了Glenn Maynard的答案(没有打印)
    基于此,cython版本非常简单,对于一个新的python程序员来说已经足够简单了:

    def main():
        cdef int i = 0
        cdef int a = 0
        while i < 6553500:
            i += 1
            if i != 6553500:
                a = i
            else:
                pass  # print "0"
        return a
    
    if __name__ == "__main__":
        print main()
    

    在我的电脑上,python版本需要2.5s,cython版本需要5.5ms:

    In [1]: import pyximport
    
    In [2]: pyximport.install()
    
    In [3]: import spam  # pure python version
    
    In [4]: timeit spam.main()
    1 loops, best of 3: 2.41 s per loop
    
    In [5]: import eggs  # cython version
    
    In [6]: timeit eggs.main()
    100 loops, best of 3: 5.51 ms per loop
    

    更新:正如Glenn Maynard在评论中指出的,而i<N:i+=1不是蟒蛇。
    我测试xrange的实现。
    spam.py和Glenn Maynard的verison是一样的。py的代码是:

    def main():
        for i in xrange(6553500):
            pass
        a = i
        return a
    
    if __name__ == "__main__":
        print main()
    ~/code/note$ time python2.7 spam.py  # Glenn Maynard's while version
    6553499
    
    real    0m2.128s
    user    0m2.080s
    sys     0m0.044s
    :~/code/note$ time python2.7 foo.py  # xrange version, as Glenn Maynard point out in comment
    6553499
    
    real    0m0.618s
    user    0m0.604s
    sys     0m0.016s
    
        3
  •  1
  •   Tushar Tyagi    14 年前

    在我朋友的笔记本电脑(Windows764位,Python2.6,3GB内存)上,Python6553500只需要1秒左右,65535000只需要10秒。我想知道为什么你的电脑要花这么多时间。当我使用xrange和局部变量时,它还减少了较大输入的时间。

    我不能评论Ruby,因为它没有安装在这台计算机上。

        4
  •  -3
  •   Nakilon earlonrails    14 年前

    测试太简单了。也许在这种情况下Ruby更快。但是,当您需要处理更复杂的数据类型及其方法时,Python会占优势。Python有更多实现的“方法来实现它”,您必须选择一种,这是最简单和足够的。Ruby使用更抽象的实体,它需要的知识更少。但是,如果在Python的同一个任务中有可能深入到手册中,并找到越来越多的类型和方法/函数的组合,那么以后就有可能比Ruby更快地编写程序。

    UPD:虽然Ruby和Python有很多共同点,但是性能和高级别将具有相反的比例性。