I find that simple things like function calls and loops, and even just loops incrementing a counter take far more time in Python and Ruby than in Chicken Scheme, Racket, or SBCL.
Why is this so? I often hear people say that slowness is a price you pay for dynamic languages, but Lisps are very dynamic and are not ridiculously slow (they are usually less than 5 times slower than C; Ruby and Python can go into the double digits). Besides, Lisp style uses recursion, and not always tail recursion, a lot, the stack is a linked list of continuations in the heap, etc, which seem to be things that should make Lisp slower than the imperative-style Python and Ruby.
Racket and SBCL are JITted, but Chicken Scheme is either statically compiled, or uses a non-optimizing interpreter, both of which should be badly suited to dynamic languages and slow. Yet even using the naive csi
interpreter for Chicken Scheme (which doesn't even do bytecode compilation!), I get speeds far beyond Python and Ruby.
Why exactly are Python and Ruby so ridiculously slow compared to the similarly dynamic Lisps? Is it because they are object oriented and need huge vtables and type heirarchies?
Example: factorial function. Python:
def factorial(n):
if n == 0:
return 1
else:
return n*factorial(n-1)
for x in xrange(10000000):
i = factorial(10)
Racket:
#lang racket
(define (factorial n)
(cond
[(zero? n) 1]
[else (* n (factorial (sub1 n)))]))
(define q 0)
(for ([i 10000000])
(set! q (factorial 10)))
Timing results:
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
转载于:https://stackoverflow.com/questions/19877268/why-are-python-and-ruby-so-slow-while-lisp-implementations-are-fast
Compiled Lisp systems are usually quite a bit faster than Ruby or Python.
See for example a comparison of Ruby and SBCL:
http://benchmarksgame.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=sbcl&data=u32
or Python and SBCL:
http://benchmarksgame.alioth.debian.org/u32/benchmark.php?test=all&lang=python3&lang2=sbcl&data=u32
But keep in mind the following:
Also some operations may look similar, but could be different. Is a for
loop iterating over an integer variable really the same as a for
loop which iterates over a range?
I think that rather than Python being slow itself, that it is the Python interpreter moving through the code at a slower rate. If you tried to compile the code with a tool such as py2exe then it may be quicker than lisp. You'd have to try it, but I think it just has a slow interpreter.
I don't know about your racket installation, but the Racket I just apt-get install
'd uses JIT compilation if run without flags. Running with --no-jit
gives a time much closer to the Python time (racket
: 3s, racket --no-jit
: 37s, python
: 74s). Also, assignment at module scope is slower than local assignment in Python for language design reasons (very liberal module system), moving the code into a function puts Python at 60s. The remaining gap can probably be explained as some combination of coincidence, different optimization focus (function calls have to be crazy fast in Lisp, Python people care less), quality of implementation (ref-counting versus proper GC, stack VM versus register VM), etc. rather than a fundamental consequence of respective the language designs.
Method dispatch in Ruby/Python/etc is expensive, and Ruby/Python/etc programs compute primarily by calling methods. Even for
loops in Ruby are just syntactic sugar for a method call to each
.