我发现像函数调用和循环这样的简单事情,甚至只是循环增加一个计数器,在Python和Ruby中的时间比远多于鸡计划,球拍或SBCL。
为什么会这样?我经常听到有人说慢速是你为动态语言付出的代价,但是Lisps非常动态并且速度不是很慢(它们通常比C慢不到5倍; Ruby和Python可以达到两位数)。此外,Lisp样式使用递归,并不总是尾递归,很多,堆栈是堆中的连续列表等,这似乎是使Lisp比命令式样Python和Ruby慢的东西。 / p>
Racket和SBCL是JITted,但Chicken Scheme要么静态编译,要么使用非优化解释器,这两种解释器都应该非常适合动态语言而且速度慢。然而,即使使用朴素csi
解释器进行Chicken Scheme(甚至不进行字节码编译!),我的速度远远超出了Python和Ruby。
与类似的动态Lisps相比,为什么Python和Ruby的速度如此之慢?是因为它们是面向对象的,需要巨大的vtable和类型heirarchies?
示例:阶乘函数。的Python:
def factorial(n):
if n == 0:
return 1
else:
return n*factorial(n-1)
for x in xrange(10000000):
i = factorial(10)
球拍:
#lang racket
(define (factorial n)
(cond
[(zero? n) 1]
[else (* n (factorial (sub1 n)))]))
(define q 0)
(for ([i 10000000])
(set! q (factorial 10)))
计时结果:
ithisa@miyasa /scratch> time racket factorial.rkt
racket factorial.rkt 1.00s user 0.03s system 99% cpu 1.032 total
ithisa@miyasa /scratch> time python factorial.py
python factorial.py 13.66s user 0.01s system 100% cpu 13.653 total
答案 0 :(得分:17)
编译的Lisp系统通常比Ruby或Python快得多。
例如,参见Ruby和SBCL的比较:
http://benchmarksgame.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=sbcl&data=u32
或Python和SBCL:
http://benchmarksgame.alioth.debian.org/u32/benchmark.php?test=all&lang=python3&lang2=sbcl&data=u32
但请记住以下内容:
此外,某些操作可能看起来相似,但可能会有所不同。迭代整数变量的for
循环是否与迭代范围的for
循环完全相同?
答案 1 :(得分:12)
Ruby / Python / etc中的方法调度很昂贵,而Ruby / Python / etc程序主要通过调用方法来计算。甚至Ruby中的for
循环只是对each
的方法调用的语法糖。
答案 2 :(得分:2)
我不知道您的球拍安装,但是如果没有标志运行,我只是apt-get install
使用JIT编译。使用--no-jit
运行的时间更接近Python时间(racket
:3s,racket --no-jit
:37s,python
:74s)。此外,出于语言设计原因,模块范围内的赋值比Python中的局部赋值慢(非常自由的模块系统),将代码移动到函数中将Python放在60s。剩余的差距可能可以解释为巧合的一些组合,不同的优化焦点(函数调用必须在Lisp中快速疯狂,Python人更少关心),实现质量(ref-counting与正确的GC,堆栈VM与寄存器VM)等等,而不是语言设计的基本结果。
答案 3 :(得分:-4)
我认为不是Python本身就很慢,而是Python解释器以较慢的速度移动代码。如果您尝试使用py2exe等工具编译代码,那么它可能比lisp更快。你必须尝试一下,但我认为它只是一个缓慢的翻译。