title: Why are Python and Ruby so slow, while Lisp implementations are fast?
body: <p>I find that simple things like function calls and loops, and even just loops incrementing a counter take <strong>far</strong> more time in Python and Ruby than in Chicken Scheme, Racket, or SBCL.</p>
  <p>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.</p>
  <p>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 <code>csi</code> interpreter for Chicken Scheme (which doesn't even do bytecode compilation!), I get speeds far beyond Python and Ruby.</p>
  <p>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?</p>
  <p>Example: factorial function. Python:</p>
  <pre><code>def factorial(n):
      if n == 0:
          return 1
      else:
      return n*factorial(n-1)
  
  for x in xrange(10000000):
      i = factorial(10)
  </code></pre>
  <p>Racket:</p>
  <pre><code>#lang racket
  
  (define (factorial n)
    (cond
     [(zero? n) 1]
     [else (* n (factorial (sub1 n)))]))
  
  (define q 0)
  
  (for ([i 10000000])
    (set! q (factorial 10)))
  </code></pre>
  <p>Timing results:</p>
  <pre><code>ithisa@miyasa /scratch&gt; time racket factorial.rkt
  racket factorial.rkt  1.00s user 0.03s system 99% cpu 1.032 total
  ithisa@miyasa /scratch&gt; time python factorial.py
  python factorial.py  13.66s user 0.01s system 100% cpu 13.653 total
  </code></pre>