Morph AppSpace - Platform as a Service for RoR

Holy Shmoly, Ruby 1.9 smokes Python away!

Antonio Cangiano November 28th, 2007

Alright the title of this post is a tad sensational sounding, I know, and it’s in part aimed at messing with my many Pythonista friends. We Rubyists have been teased for a long time, due to the slowness of the main Ruby interpreter. Well, it looks like with Ruby 1.9, it’ll be payback time. Just out of curiosity I decided to run a single benchmark (you can hardly call it that) to see how Ruby 1.9 had improved over the current stable version (1.8.6). I wasn’t planning to make a post about it. It was one of those tests that you do at 3 AM in an irb session when you feel you’ve made your daily peace with your actual workload for the night. When I saw the results though, my jaw dropped. I had to blog about this one.

I ran a recursive Fibonacci function, just to stress test a bit of recursion and method calling, and while I was at it, I decided to compare it with Python too. The test was run on Mac OS X 10.5 with my MacBook Pro (Core 2 Duo 2.2 GHz and 2 GB of memory). It’s a single test (which is obviously not a real world example, as you would use an iterative version of the function if it were), and unlike with real programs, it doesn’t stress many features of the language. At least for now, there is no reasonable evidence to conclude that Ruby 1.9 - which will be released for this coming Christmas - will actually be faster than Python 2.5.1 in the majority of situations, but hear me out and check out these very surprising results.

The Ruby code:

def fib(n)
  if n == 0 || n == 1
    n
  else
    fib(n-1) + fib(n-2)
  end
end

36.times do |i|
  puts "n=#{i} => #{fib(i)}"
end

And the Python equivalent:

def fib(n):
   if n == 0 or n == 1:
      return n
   else:
      return fib(n-1) + fib(n-2)

for i in range(36):
    print "n=%d => %d" % (i, fib(i))

Running the snippets above, I got the following results:

Ruby 1.8.6:       158.869s
Python 2.5.1:      31.507s
Ruby 1.9.0:        11.934s

Ehm, hold on a second! Did Ruby just go from 159 seconds down to 12? Koichi Sasada, do you have an Amazon Wishlist? I was expecting a decent improvement, as I’ve been playing with 1.9 every now and then for a long time - so I knew it was faster - but I was blown away when I timed the latest version from trunk (even if it’s a really silly example that’s being tested). Granted Python is not the fastest language out there, but Ruby 1.9 was still able to execute the script almost 3 times as fast. It’s unbelievable.

Now it’ll be very interesting to run a series of algorithmically equivalent tests for Ruby and Python, and to see just when exactly Ruby 1.9 manages to knock Python out of the water - and where Python has still the edge. If I manage to find some time, I will report the results in this blog. But for now, I’ll say just… wow!


If you enjoyed this post, then make sure you subscribe to my RSS Feed.

91 Responses to “Holy Shmoly, Ruby 1.9 smokes Python away!”

  1. Bruno FRANCE Ubuntu Linux Mozilla Firefox 2.0.0.8 on 28 Nov 2007 at 6:13 am

    I guess the difference between Ruby 1.9 and Python 2.5 mostly may comes from Python not optimizing tail-recursive calls (which btw is a design choice wrt/ ease of debugging, not a technical flaw).

    But indeed, the speed-up between Ruby 1.8 and 1.9 is, well… wow !-)

  2. karim Mac OS X Netscape Navigator 5.0 on 28 Nov 2007 at 6:37 am

    What about psyco? have you tried it?
    http://psyco.sourceforge.net/

  3. vuk CROATIA Windows XP Flock 1.0.1 on 28 Nov 2007 at 6:39 am

    There are lies, damn lies and Benchmarks… ;-)

  4. Christian DENMARK Mac OS X Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 7:03 am

    Does Ruby 1.9 optimize tail recursive calls? That’s great. Can you post a link where this is documented?

  5. xtian UNITED KINGDOM Windows XP Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 7:03 am

    Bruno, I thought it might have been that at first, but the recursive calls aren’t tail calls.

    Looks like Ruby’s function call overhead might be less than Python’s?

  6. gnufied INDIA Ubuntu Linux Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 7:03 am

    Bruno:

    That function can’t be optimized by tail-recursive calls. Tail-recursion kicks in, only when your procedure is recursive, but process is iterative. Also, ruby never had any tail recursion.

    The performance is mainly because of special handling of fixed point maths by new VM that Ruby 1.9 provides….

  7. Oliver GERMANY Mac OS X Safari 523.10 on 28 Nov 2007 at 7:10 am

    Oh yeah. The next sensational headline supported by an artificial benchmark. :) But I’m more then happy, that ruby is getting faster, even though I turned away from it and back to my beloved Python.

  8. Ruby1.9 vs Python 2.5.1 « Andrei Maxim WordPress MU on 28 Nov 2007 at 7:12 am

    […] 28, 2007 in nout??iTags: python, ruby19 Antonio Cangiano a f?cut un mic test cu Python 2.5.1 ?i Ruby 1.9, rulând o func?ie care calculeaz? ?irul lui Fibonacci […]

  9. Greg Graham UNITED STATES Windows XP Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 7:26 am

    As a Python user that has enjoyed doing some Ruby in the past, I’m glad to see that Ruby performance is improving. Congratulations! (I don’t get into the language wars. Python is the best solution for my current situation, but I admire Ruby.)

  10. Andrew Ingram UNITED KINGDOM Windows XP Mozilla Firefox 2.0.0.9 on 28 Nov 2007 at 7:46 am

    I imagine that like many I’m skeptical about the true level of improvement, I’m eager to see some more thorough benchmarks :)

    But still, assuming it’s not a one off thing, that’s a pretty impressive speedup and could end up making Ruby much more competitive as an enterprise-level language.

  11. she AUSTRIA Linux Mozilla Firefox 2.0.0.6 on 28 Nov 2007 at 7:56 am

    Well of course I am biased since I use ruby and not python (but I never can understand a conflict between ruby and python, i am always saying to join up to beat on common enemies… perl and php and of course legacy shell scripts or solutions ESPECIALLY if they use perl ;) )

    But what can be roughly said is that it seems ruby-1.9 will be faster than 1.8, and this alone is the most important difference anyway!

  12. Antonio Cangiano Mac OS X Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 7:57 am

    I wholeheartedly agree with you Andrew.

  13. Chris Khoo AUSTRALIA Ubuntu Linux Mozilla Firefox 2.0.0.6 on 28 Nov 2007 at 8:26 am

    “Mmmm.. yes fascinating,” he mumbles as he switches back to his vim window editing C source.

  14. Leonardo BRAZIL Windows XP Internet Explorer 6.0 on 28 Nov 2007 at 8:39 am

    It is really goo to hear that as one of my main concerns today is ruby’s speed!

    Thanks man!

  15. foo AUSTRALIA Debian GNU/Linux Konqueror 3.5 on 28 Nov 2007 at 8:46 am

    Wow. I’m impressed by how much Ruby manages to uglify simple code snippets.

  16. arman PHILIPPINES Windows XP Mozilla Firefox 2.0 on 28 Nov 2007 at 9:19 am

    wow…Ruby is getting faster compared to python. But it doesnt mean, ruby is more powerful than python. anyway, i still love php. ;-)

  17. Twisted Electricityon 28 Nov 2007 at 9:46 am

    Python has very slow recursion performance

    Just today I read a post from Antonio showing how big of an improvement Ruby …

  18. dyork AUSTRALIA Windows XP Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 10:04 am

    Reality check: C# 1.4 secs.

  19. Del Ben Oscar ITALY Mac OS X Safari 523.10 on 28 Nov 2007 at 10:12 am

    That’s cool thanks for sharing, i hope to do some benchamarks between 1.8 and 1.9

  20. Ola Bini UNITED KINGDOM Mac OS X Mozilla Firefox 2.0.0.9 on 28 Nov 2007 at 10:24 am

    First, Ruby 1.9 has tail call analysis, but doesn’t use it for anything right now. They might include optimization later, but that’s not there yet.
    General performance improvement for 1.9 is looking to be about 150% to 200% for most applications, based on more real world test cases.

    Note that JRuby trunk now actually performs even better on recursive fib than Ruby 1.9.

  21. Dima Dogadaylo UKRAINE Ubuntu Linux Mozilla Firefox 2.0.0.6 on 28 Nov 2007 at 10:26 am

    Antonio, Python can calculate first 35 Fibo numbers in hundreds of times faster than Ruby. You just need to use right tools for right tasks. For example try to execute on your workstation:

    def fib():
    a, b = 0, 1
    while True:
    yield a
    a, b = b, a + b

    f = fib()
    for i in range(36):
    print “n=%d => %d” % (i, f.next())

    on my workstation it takes less than 0.1 second:
    $ time python2.5 fibo.py
    real 0m0.075s
    user 0m0.020s
    sys 0m0.028s

  22. pp ITALY Linux Opera 9.24 on 28 Nov 2007 at 11:00 am

    Yay, now you just need to take it to the next level. ;)

    $ cat /proc/cpuinfo | grep name
    model name : Intel(R) Pentium(R) III Mobile CPU 1133MHz

    CL-USER> (defun fibo (n)
               (if (<= (1- n) 0) n
                   (+ (fibo (- n 1)) (fibo (- n 2)))))
    STYLE-WARNING: redefining FIBO in DEFUN
    CL-USER> (defun test ()
               (dotimes (i 36)
                 (format t "n=~a => ~a~%" i (fibo i))))
    STYLE-WARNING: redefining TEST in DEFUN
    CL-USER> (time (test))
    [...]
    Evaluation took:
      7.734 seconds of real time
      7.176449 seconds of user run time
      0.004 seconds of system run time
      0 calls to %EVAL
      0 page faults and
      212,424 bytes consed.

    But, hey. We can do better.
    CL-USER> (defun fibo (n)
               (declare (optimize speed (safety 0) (debug 0))
                        (fixnum n))
               (if (<= (1- n) 0) n
                   (the fixnum (+ (fibo (- n 1)) (fibo (- n 2))))))
    STYLE-WARNING: redefining FIBO in DEFUN
    CL-USER> (time (test))
    [...]
    Evaluation took:
      2.129 seconds of real time
      1.948121 seconds of user run time
      0.0 seconds of system run time
      0 calls to %EVAL
      0 page faults and
      179,528 bytes consed.

  23. Thomas Güttler GERMANY SuSE Linux Mozilla Firefox 1.5.0.4 on 28 Nov 2007 at 11:12 am

    A language is fast, if the development progress is fast. This means C is slow, python and ruby are fast.

    If the ruby interpreter can execute faster than python, the python folks will try to improve python.

    I like python because the standard library is great and it has built in unicode support.

    Does ruby1.9 give you built in unicode support?

  24. Anurag INDIA Ubuntu Linux Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 11:13 am

    Heh, day by day, python vs. ruby is becoming more like vi/emacs wars!

  25. Bob Holness UNITED STATES Windows XP Mozilla Firefox 3.0b1 on 28 Nov 2007 at 11:20 am

    This just goes to prove how crap Python is. ;)

    (BTW, what is Python?)

  26. Jaroslaw Zabiello IRELAND Mac OS X Opera 9.24 on 28 Nov 2007 at 11:21 am

    Ech, Python 2.4.4 + psyco gives: 2.5 sek :-D

  27. tim UNITED STATES Windows XP Mozilla Firefox 2.0.0.6 on 28 Nov 2007 at 11:23 am

    On my PC, python takes 20 secs without psyco. With psyco, only 1.5 secs!

  28. Jan Rychter POLAND Mac OS X Mozilla Firefox 2.0.0.9 on 28 Nov 2007 at 11:57 am

    Well, since you’re comparing high-level languages… I quickly coded a silly implementation in Common Lisp.

    (in-package #:cl-user)

    (defun fib (n)
    (declare (optimize (speed 3) (space 0) (safety 0) (debug 0)))
    (if (or (eql n 0) (eql n 1))
    n
    (+ (fib (- n 1)) (fib (- n 2)))))

    (time (loop for i from 0 to 35
    do (format t “~A => ~A~&” i (fib i))))

    ; cpu time (total) 920 msec user, 10 msec system
    ; real time 924 msec

    This is on the same type Macbook Pro that you’ve used, where the python version takes 31s.

    I guess having a compiler (which can compile things entered interactively!) is a bit of an advantage. So I’m curious as to why people would still prefer languages without one.

    –J.

  29. mkaatman UNITED STATES Ubuntu Linux Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 12:04 pm

    And how about PHP 5 for good measure?

    <?php
    function fib($n)
    {
    if( $n == 0 || $n == 1 )
    return $n;
    else
    return fib($n-1) + fib($n-2);
    }

    for( $i=0; $i #’.fib($i).”\n”;
    }

    Took about 74 seconds on my box using:
    PHP 5.2.3-1ubuntu6 (cli) (built: Oct 4 2007 23:35:54)

    Irrelevant to compare to his numbers but looks like it’s slow compared to the new ruby or python.

  30. Martin Vilcans SWEDEN Windows 2000 Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 12:16 pm

    That’s an impressive speedup, but of course it just tests one little special case (a.k.a. a microbenchmark). Why don’t you go to the computer language shootout (http://shootout.alioth.debian.org/) and test all of their microbenchmarks. It would still be anecdotal evidence, but at least it would be more than just one microbenchmark.

  31. sapphirecat UNITED STATES Linux Mozilla 1.8.1.8 on 28 Nov 2007 at 12:30 pm

    Instead of doing all that benchmarking yourself, you should borrow someone else’s. Have a look on the Pentium-4 sandbox of the famous Computer Language Shootout: http://shootout.alioth.debian.org/

  32. Larry McVoy UNITED STATES Debian GNU/Linux Mozilla Firefox 2.0.0.8 on 28 Nov 2007 at 12:36 pm

    We’ve got a little set of test cases for various languages (including a new one we’ve built for internal use but are releasing as open source in case anyone else wants to play with it) and the results are improved but nowhere near as impressive as this thread implies.

    lang cat grep hash loop proc sort wc
    pl 0.35 0.36 0.63 0.11 0.30 2.03 1.03
    py 0.37 1.08 0.46 0.18 0.17 1.83 0.48
    rb 0.83 0.86 1.98 0.31 0.52 3.32 2.29
    rb-snap 0.74 0.79 1.39 0.04 0.06 3.04 1.44
    tcl 0.97 0.78 1.24 0.07 0.24 3.76 0.97
    l 1.01 0.78 1.32 0.07 0.24 4.15 1.60

    Here’s the langbench README:

    langbench is a simplistic set of microbenchmarks designed to see how well
    a scripting language performs at basic operations.

    We (BitMover) are using it to benchmark our scripting language, you can
    use it for whatever you like.

    Copyright (c) 2007 by BitMover, Inc.
    You may use for any purpose provided that if you use the “langbench” name
    you report all results for all languages like so:

    langbench version 0.5 results:
    lang cat grep hash loop proc sort split
    pl 0.85 0.85 1.38 0.24 0.68 4.72 5.13
    py 0.81 2.97 1.03 0.34 0.40 4.37 1.56
    rb 1.81 1.68 4.18 0.53 1.04 8.00 3.66
    tcl 2.02 1.45 2.44 0.13 0.72 7.48 3.93
    l 2.02 1.48 2.43 0.12 0.73 8.11 3.94

    with the exception that you may leave off the L language until it is
    widely distributed (defined as apt-get install l).

    Test descriptions:
    cat copy stdin to stdout
    grep match a regular expression against stdin, print each match
    hash use each line of stdin as a hash key, value is 1.
    loop measure the cost of a loop
    proc measure procedure call cost
    sort sorts stdin to stdout
    wc implements wc in a hand coded way

    Input data is a million lines of code generated like this:

    for i in 1 2 3 4 5 6 7 8 9 0
    do cat tcl/generic/*.[ch]
    done | head -1000000 > DATA

    This file and tests are at http://www.bitmover.com/lm/langbench.shar

  33. […] real point to take from Antonio Cangiano’s article, Holy Shmoly, Ruby 1.9 smokes Python away!, is not that Ruby 1.9 runs circles around Python, but that Ruby 1.9’s performance appears to […]

  34. Dima Dogadaylo UKRAINE Ubuntu Linux Mozilla Firefox 2.0.0.6 on 28 Nov 2007 at 1:29 pm

    Ruby 1.9 doesn’t smoke Python away!

    Antonio Cangiano compared execution time of recursive Fibonacci function written in Python and Ruby 1.9 and found that Ruby variant was almost 3 times as fast. It allowed him to write blog entry titled “Holy Shmoly, Ruby 1.9 smokes Python away!”. It’s time to show secret Python weapon – calculation of same Fibonacci numbers but in 1000 times faster than Antonio’s Ruby implementation.

    http://www.mysoftparade.com/blog/ruby-19-doesnt-smoke-python-away/

  35. dataangel UNITED STATES Ubuntu Linux Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 1:45 pm

    @gnufied: Why isn’t it tail recursive? Looks like it to me. Just to make sure I wasn’t crazy I checked wikipedia and it says a tail recursive is when the last instruction is a recursive call, which those defs of fib fit.

  36. Sobe FRANCE Windows XP Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 1:47 pm

    Wowowow !!!

    Really a beautiful Christmas present it seems !

    By the way, I don’t really understand how you can improve a language to make it 15 times speeder on so simple script… 8|

    Let’s take good news without too many questions ;)

  37. Andrew UNITED STATES Ubuntu Linux Mozilla Firefox 2.0.0.8 on 28 Nov 2007 at 1:57 pm

    Nevermind that 1.9 comes with a VM…

    Isn’t it possible the code is compiled to bytecode and then run through the VM?

  38. toreau NORWAY Ubuntu Linux Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 2:05 pm

    Bad choice of a benchmark, as the Fibonacci function can be cached. Using the Memoize module in Perl, I can perform the same calculation in 0.024 seconds on my Athlon64 3700+;

    #!/usr/bin/perl
    #
    use strict;
    use warnings;

    use Memoize;
    memoize( ‘fib’ );

    for ( 0..36 ) {
    print $_ . ‘ => ‘ . fib($_) . “\n”;
    }

    sub fib {
    my $n = shift || 0;
    return $n if ( $n < 2 );
    return fib( $n-1 ) + fib( $n-2 );
    }

  39. Logan UNITED STATES Windows XP Internet Explorer 6.0 on 28 Nov 2007 at 2:09 pm

    @dataangel: +. The last call is +. fib(n - 1) + fib(n - 2) —> a = fib(n - 1); b = fib(n - 2); a + b

  40. mfp SPAIN Debian GNU/Linux Mozilla Firefox 2.0.0.2 on 28 Nov 2007 at 2:27 pm

    dataangel: it’s not tail-recursive, there’s an addition after the fib(n-1) and fib(n-2) calls.
    Andrew: yes, the above code *is* run through the VM (ruby 1.9 doesn’t have an AST walker anymore).

    I am not impressed by the results of this micro-benchmark (probably because I’m well-informed regarding Ruby 1.9); it’s always been well-known that 1.9 can be over 5 times faster than ruby 1.8 in such simplistic tests (in this case, the gains come mainly from the integer op optimizations introduced in YARV). The speedup is much more modest for more realistic tasks, and a few things are slower in 1.9.

    IMO titles like “Ruby 1.9 smokes Python away!” inspire the wrong kind of reactions. (As tempting as they are, catchy headlines are best avoided if you care about the quality of the discussion more than about the number of visits.)

  41. pp ITALY Linux Opera 9.24 on 28 Nov 2007 at 2:35 pm

    Hey friends. Here the benchmark is on *FUNCTION CALLS*, not on generating fibonacci numbers. *Of course* iterative or memoized algorithms are WAY faster. But in this version, to call fib() on every number from 0 to 35 means that we are measuring 78,176,300 function calls.

  42. Isaac Gouy UNITED STATES Linux Epiphany 2.20 on 28 Nov 2007 at 3:12 pm

    Nice that a couple of people mentioned the benchmarks game, looking at the recursive benchmark we’d see Ruby 1.9.0 doing 1.7x better than Python.

    http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=yarv&lang2=python

    Does anyone know how to increase the stack size in Ruby 1.9.0 - there’s an unhappy program -

    http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=recursive&lang=yarv&id=2#log

  43. Matthew IRELAND Linux Mozilla Firefox 2.0.0.9 on 28 Nov 2007 at 3:23 pm

    And for cold reality itself:

    #include
    unsigned long fib(int i) {
    if (i == 0 || i == 1)
    return 1;
    return fib(i - 1) + fib(i - 2);
    }
    int main() {
    int i = 0;
    for (i = 0; i %ld\n”, i, fib(i));
    return 0;
    }

    gcc -O6 -o fib fib.c

    0.339 seconds.

  44. raggi UNITED KINGDOM Windows XP Mozilla Firefox 2.0.0.9 on 28 Nov 2007 at 3:46 pm

    It’s probably worth pointing out that this is the test that YARV (1.9) is really optimised for, and is not a fair representation of YARVs speed at processing general ruby apps.

    Also, if you haven’t seen it already, check Charles’ post about JRuby and this particular benchmark:
    http://headius.blogspot.com/2007/11/java-6-port-for-os-x-tiger-and-leopard.html

    $0.02,

    Enjoy.

  45. bascule UNITED STATES Windows XP Mozilla Firefox 2.0.0.10 on 28 Nov 2007 at 4:06 pm

    That function can most certainly be made tail recursive. Here’s an Erlang version:

    fib(N) -> fib(N, 1, 0).
    fib(0, _, Result) -> Result;
    fib(N, Next, Result) -> fib(N - 1, Next + Result, Next).

  46. Dan CANADA Mac OS X Safari 523.10 on 28 Nov 2007 at 4:20 pm

    @she: I don’t think there’s that much conflict between the Ruby and Python communities. During this year’s RubyConf Keynote, Matz unbuttoned his shirt to show he was wearing a Python shirt underneath so there can’t be that much conflict:

    http://www.flickr.com/photos/john_lam/1910968816/

    Maybe there’s some friendly rivalry, but that only helps everyone improve. I’m a Ruby guy, but I think Python is a beautiful language.. most Ruby people I talk to think the same way.

  47. Charles Oliver Nutter UNITED STATES Mac OS X Mozilla Firefox 2.0.0.9 on 28 Nov 2007 at 6:20 pm

    On my system, JRuby finishes in about 23 seconds to Ruby 1.9’s 13 seconds. Not bad considering JRuby doesn’t have any integer math optimizations like Ruby 1.9 does. I think we can close the gap.

  48. Ruby 1.9 « .dscape WordPress MU on 28 Nov 2007 at 7:51 pm

    […] têm acontecido na minha universidade (mais uma vez), achei relevante o post que ele fez sobre a performance do Ruby 1.9. Aconselho a leitura. Fica, como resumo, os resultados obtido comparando a função de fibbonacci […]

  49. » The Links » roarin’ reporter WordPress 2.3.1 on 28 Nov 2007 at 10:16 pm

    […] Holy Shmoly, Ruby 1.9 smokes Python away! […]

  50. Paolo Bonzini ITALY Mac OS X Mozilla Firefox 2.0.0.10 on 29 Nov 2007 at 7:01 am

    Ahem, your ruby program does *not* compute f(36) it only goes up to f(35). So I’m not sure Ruby 1.9 is much faster than Python; however it is impressive compared to Ruby 1.8.

    Here are my results for another pair of languages:

    Python 2.5 0m15.657s
    GNU Smalltalk 2.95f 0m4.594s

  51. Paw Prints » Blog Archive » Parallelism UNITED STATES WordPress 2.0.5 on 29 Nov 2007 at 10:16 am

    […] following a series of posts that started with this one, moved to this one and, so far, has reached this one. To save you the bother of reading these the […]

  52. Jaroslaw Zabiello IRELAND Mac OS X Opera 9.24 on 29 Nov 2007 at 10:54 am

    For MacBook Pro, 2.2GHz, Leopard 10.5.1:

    Ruby 1.8.6: 50s
    Ruby1.9 edge: 12s
    JRuby edge: 45s
    JRuby edge -J-server: 20s
    JRuby edge -J-server -J-Djruby.compile.frameless=true: 18s

    Python 2.4.4: 30s
    Python 2.4.4 + psyco: 1.8s (sic!)
    Python 2.5.1: 54s

  53. ARJ UNITED STATES Windows XP Mozilla Firefox 2.0.0.10 on 29 Nov 2007 at 11:44 am

    I like toreau pointing out that algorithmic consideration can have a huge effect, especially when folks are in the ‘yeah, well my obscure language of choice does it in N secs’ mode.

    Ruby memoize version looks like the Perl version, minus some line noise and shifting and such cool things (although both have been my obscure language of choice at various times):

    require “memoize”

    def fib(n)
    return n if(n < 2)
    fib(n-1) + fib(n-2)
    end

    memoize(:fib)

    # TODO: use fib, make benchmark claims

    Nice to see the improvements in the Ruby interpreter and JRuby as a viable alternative. Yay, those guys.

  54. […] http://antoniocangiano.com/2007/11/28/holy-shmoly-ruby-19-smokes-python-away/ […]

  55. Links on a more serene thursday FRANCE WordPress 2.1.2 on 29 Nov 2007 at 3:27 pm

    […] the expression ‘Holy Schmoly’ before. Now in two days i’ve read it twice, and both times in the context of computing languages performance. Two times too often, if you ask me. But […]

  56. Antonio Cangiano Windows XP Mozilla Firefox 2.0.0.10 on 29 Nov 2007 at 3:29 pm

    Paolo wrote:
    > Ahem, your ruby program does *not* compute f(36) it only goes up to f(35). So I’m not sure Ruby 1.9 is much faster than Python; however it is impressive compared to Ruby 1.8.

    Paolo, both programs compute up to f(35). :)

  57. SwitchBL8 NETHERLANDS Ubuntu Linux Mozilla Firefox 2.0.0.10 on 29 Nov 2007 at 6:37 pm

    I’m not sure how much slower a Core2Duo 2.2GHz is than a AMD X2 6000+, but on my system the Python version finishes in well under a second. So how can yours run for 31 seconds? That’s almost 1 second for every fib-number.

    Done with Python 2.5.1 on 64bits Ubuntu.

    I don’t have Ruby 1.9, but 1.8.6 runs about two minutes, that’s approx. 120 seconds. So Python (in this case) on my system is about 120 times faster than Ruby, how can yours only be 6 times faster? There’s something wrong with your system or your Python for sure.

  58. Antonio Cangiano Windows XP Mozilla Firefox 2.0.0.10 on 29 Nov 2007 at 7:25 pm

    SwitchBL8, my Python results were confirmed by people with similar hardware to mine. No one reported a significantly lower number than what I got. You have an excellent CPU there, but running the Python script in under a second seems like an unrealistic result. Are you sure you have just cut and pasted my snippet without altering anything? Iterative versions of the same script run in well under a second, this is true for both Ruby and Python, but the recursive one (without psyco or memoization) shouldn’t.

  59. ictboy CHINA Windows XP Mozilla Firefox 2.0.0.10 on 30 Nov 2007 at 4:35 am

    a faster algorithm,using python,0.6 sec.
    >>> d={}
    >>> def fib(n):
    … if n==0 or n==1:
    … return n
    … if d.has_key(n):
    … return d[n]
    … else:
    … temp = fib(n-1) + fib(n-2)
    … d[n] = temp
    … return temp

    >>> for i in range(36):
    … print “n=%d => %d” % (i, fib(i))

  60. […] Haskell, Ruby Smackdown November 30, 2007 Antonio Cangiano writes about how the new and improved Ruby 1.9 is actually faster than Python for a fibonacci […]

  61. vicalloy CHINA Windows XP Opera 9.23 on 30 Nov 2007 at 10:09 am

    in my computer:
    jdk1.6 52594/100= 0.52594s
    delphi7 1m05s/100= 0.65s
    VC6 1m11s/100= 0.71s
    C#(.net2.0) 14s121/10= 1.4121s
    python2.5 52s
    ruby1.86 2m24s

  62. […] Announcing Publicity - A brand new language designed to smoke any other language out there. Some examples: […]

  63. […] My post about Ruby 1.9’s impressive improvement over Ruby 1.8.6 created quite an echo within the developer community. Sure, the headline was an attention grabber, just like this one is :-P, but in a matter of a few hours, there were all sorts of blog entries with variants in many languages, more than 200 comments on Reddit, and fifty comments on my own blog. There were however, also a few misconceptions. It was great though because such a simple post generated a lot of discussion amongst developers, with some insightful arguments taking place - and besides it almost created a new meme with the whole “holy shomly” thing. Fun as that certainly was, let’s try to summarize and clarify a few points. […]

  64. niko GERMANY Mac OS X Safari 523.12 on 01 Dec 2007 at 8:01 am

    A very fast fib snippet in Ruby:

    Fibonacci numbers in Ruby

    http://snippets.dzone.com/posts/show/3562

  65. Dinomite.net » Perl, Python and Ruby UNITED STATES WordPress 2.1.2 on 01 Dec 2007 at 11:34 am

    […] reading this article comparing the new Ruby 1.9 to it’s older version and Python, I though it would be interesting […]

  66. clorophilla.blog ITALY WordPress 2.3.1 on 01 Dec 2007 at 12:05 pm

    Microbenchmark: Ruby 1.9.0 contro tutti (… non proprio…)

    Il rilascio di Ruby 1.9 è previsto intorno a Natale e con il passare dei giorni la curiosità dei rubyisti si fa sempre più intensa. Stuzzicato da un microbenchmark pubblicato da Antonio Cangiano sul suo blog in cui ha messo a confronto l…

  67. SwitchBL8 NETHERLANDS Ubuntu Linux Mozilla Firefox 2.0.0.10 on 02 Dec 2007 at 6:34 am

    @Antonio: I stand corrected. I used:

    #!/usr/bin/env python
    
    def fib(n):
      return fib_r(0, 1, n)
    
    def fib_r(cur, next, rem):
      if rem == 0:
        return cur
      else:
        return fib_r(next, cur + next, rem - 1)
    
    for i in range(36):
        print "n=%d => %d" % (i, fib(i))
    

    instead of yours. Results:

    real 0m0.048s
    user 0m0.012s
    sys 0m0.016s

    Using your script the results are about as slow as everybody elses:

    real 0m24.502s
    user 0m23.837s
    sys 0m0.496s

    So I guess you can create slow programs with Python too, didn’t know that.. :-)
    See Coderspiel

  68. luke SWITZERLAND Ubuntu Linux Mozilla Firefox 2.0.0.10 on 03 Dec 2007 at 10:08 am

    my results (core2duo @ 2.4 ghz)

    antonio’s fibonacci test
    ruby 1.8.6 => 82.8s
    jruby 1.1b1 => 13.9s
    ruby 1.9 => 8.7s

    numerical test from http://numericalruby.com/2007/11/28/quick-numerical-benchmark-of-ruby-19/
    ruby 1.8.6 => 111.8s
    jruby 1.1b1 => 48.8s
    ruby 1.9 => 44.5s

    so ruby1.9 is about 2 - 10 times faster than ruby1.8

  69. Antonio Cangiano Mac OS X Safari 523.10 on 03 Dec 2007 at 11:07 am

    @luke: Later today I’ll publish “The Great Ruby Shootout”. It’s going to be fun. :)

  70. ??????? » Blog Archive » Ruby 1.9 WordPress 2.3.1 on 03 Dec 2007 at 12:32 pm

    […] Update Holy Shmoly, Ruby 1.9 smokes Python away! Ruby 1.9 doesn’t smoke Python away!  Quick numerical benchmark of Ruby 1.9 […]

  71. lvcha CHINA Windows XP Mozilla Firefox 2.0.0.11 on 05 Dec 2007 at 5:48 am

    :(
    in Java:
    0=>0
    1=>1
    2=>1
    3=>2
    4=>3
    5=>5
    6=>8
    7=>13
    8=>21
    9=>34
    10=>55
    11=>89
    12=>144
    13=>233
    14=>377
    15=>610
    16=>987
    17=>1597
    18=>2584
    19=>4181
    20=>6765
    21=>10946
    22=>17711
    23=>28657
    24=>46368
    25=>75025
    26=>121393
    27=>196418
    28=>317811
    29=>514229
    30=>832040
    31=>1346269
    32=>2178309
    33=>3524578
    34=>5702887
    35=>9227465
    time=484ms

  72. I wanna spend all your money... GERMANY on 05 Dec 2007 at 11:09 am

    […] are being generated to make “your religion language” look good against others (usually by misusing the language you want to bash). There is a semantic difference between discussing a language itself, it’s syntax, it’s standard […]

  73. Adam UNITED STATES Windows XP Mozilla Firefox 2.0.0.11 on 05 Dec 2007 at 4:43 pm

    Psyco is an impressive piece of software, but it isn’t that useful for web applications. Why? Because you don’t care so much about speed increases as you do memory usage when it comes to web applications. In fact, the leading Python framework (Django) says in their documentation that it’s memory and not processing power that makes the difference. As soon as you start swapping, you’re toast.

    As the Psyco webiste says, it uses a lot of memory. That means fewer server processes listening to requests. So, you might be cutting down some milliseconds off each request once that request gets heard, but you might also be dramatically increasing the time before an Apache process actually deals with a specific request.

    In a world where memory is more the constraint than CPU, Psyco does more harm than good.

  74. Ruby o Phyton? ITALY WordPress 2.3 on 07 Dec 2007 at 10:49 am

    […] Ruby 1.8.6: 158.869s Python 2.5.1: 31.507s Ruby 1.9.0: 11.934s […]

  75. aaa GERMANY Debian GNU/Linux Epiphany 2.20 on 10 Dec 2007 at 1:22 pm

    a trivial translation to ocaml

    let rec fib n =
    if n=0 || n=1 then n
    else fib (n-1) + fib (n-2);;

    for n = 0 to 35 do
    Printf.printf “n=%d => %d\n” n (fib n);
    done;;

    runs 100 times faster than python
    python 0m41.993s
    ocaml 0m0.455s

  76. Sturla Molden NORWAY Windows XP Mozilla Firefox 2.0.0.11 on 11 Dec 2007 at 12:24 pm

    So you have proven it takes 31.5 seconds to calculate 36 Fibonacci numbers in Python 2.5.1 if you use the dumbest possible algorithm (exponential complexity).

    For calculating the first 36 Fibonacci numbers, I found this to be 6 orders of magnitude faster, i.e. giving a speedup by a factor of a million:

    def fibo(n):
    while 1:
    try:
    return fibo.seq[n]
    except AttributeError:
    fibo.seq = [0, 1, 1]
    except IndexError:
    fibo.seq.append( fibo.seq[-2] + fibo.seq[-1] )

    A good choice of algorithm is far more important than language implementation.

  77. Antonio Cangiano Windows XP Mozilla Firefox 2.0.0.11 on 11 Dec 2007 at 12:32 pm

    Sturla, no one is disputing that. You can read my follow up here.

  78. Sturla Molden NORWAY Windows XP Mozilla Firefox 2.0.0.11 on 11 Dec 2007 at 2:26 pm

    The point I am trying to make, is that real-world performance has very little to do with the speed of the Python or Ruby interpreter measured in micro-benchmarks. Where you could make your program run tree times faster by changing the VM from Python to Ruby, you could have made it a million times faster by changing the algorithm. Claims that “Python or Ruby is so slow”, and that “C++ or Java is so much faster”, have in 99% of the cases more to do with bad programming than the platform.

    The thing that really matter is how Python or Ruby performs in the real world. And that depends mostly on the programmer. Google uses Python to run YouTube. NASA uses Python to process image data from Hubble. How slow can it be?

    If you want to make Python look really bad, you can do as Peter Norvig and use Python lists for matrix multiplication (http://norvig.com/python-lisp.html). On the other hand, I could make Python with NumPy do wavelet transforms a lot faster than Matlab. Benchmarks just tend to tell lies.

  79. ShiningRay CHINA Windows XP Mozilla Firefox 2.0.0.11 on 17 Dec 2007 at 9:36 am

    I’m wondering about the memory usage. Currently i’m working with rails and found its serious memory leak problem, but django a kind of python’s framework doesn’t have such problem.

  80. BLeAm THAILAND Linux Mozilla Firefox 3.0b3pre on 25 Dec 2007 at 7:33 pm

    Not so sure whether your point of view is specific for recursive function or not?
    If not that so, but just only fibonacci calculation,
    I’ll wonder why you have to make things complicated?
    I just simply code it as below:

    def fn(n):
    a = 0
    b = 0
    for i in range(1,n):
    c = a + b
    b = a
    a = c
    if a < 1: a += 1
    print “n=%s %s” % (i,a)
    return a

    if __name__ == ‘__main__’: fn(36)

    and the performance not so bad:
    real 0m0.043s
    user 0m0.024s
    sys 0m0.012s

    BTW, if you really really want to do it by recursive concept and strict with your code,
    just apply psyco to your code and the result is supposed to be nearly 2.4s , and that’s mean, it’s even better than your ruby code which run on ruby 1.9.
    I don’t know if there any JIT compilers in ruby?
    But in real world task, don’t avoid to use any tools which offers you with better and easier way to done job.

  81. […] have been guiding the implementation of 1.9, which above all should be much faster than 1.8 (and more competitive with other languages). More detailed changes here.Also, in case you didn’t hear, Rails 2.0 was released last month. […]

  82. HYPER HUNGARY Fedora Linux Mozilla Firefox 2.0.0.1 on 04 Jan 2008 at 7:33 am

    And here’s hand-coded IBM Cell assembly:

    fib: ENTRY
    MOV A,0
    MOV B,1
    MOV C,0
    MOV D,36 ;
    fib2: SWP A,B
    ADDR B,A,B
    INC C
    CMP C,D
    JL fib2
    end: RET B

    Runs in 182 instructions if I’m counting correctly, which is exactly 0.00000001895833333333333269601445004656770088047323952196165919303894 seconds on a single CellEB 2 core.

  83. adit INDONESIA Fedora Linux Mozilla Firefox 2.0.0.10 on 20 Jan 2008 at 9:28 am

    wow that was cool, i hope this will make great influence to RoR too

  84. Satish INDIA Windows XP Mozilla Firefox 2.0.0.11 on 08 Feb 2008 at 11:22 am

    Anything that gets a job done and done well requires to be complimented.

    We have a long way to go. I have come a long way with python, I will try and go any distance with ruby too if it is simple enough, but go I will and fast.

    If this rivalry does good great!!, if it is to stifle the other in the race for the ultimate good, we may fail to reach the ultimate destination.

    Let us remember this.

    You guys are great, and manking will always be thankful for the wonderful job you are doing, all of you EACH ONE of you.

    I for one am thankful to be living in this world with all of you.

    Spread Love Everywhere.

  85. […] with the new Parser Ruby is 3 times as fast as Python. […]

  86. JMC UNITED STATES Ubuntu Linux Mozilla Firefox 2.0.0.12 on 28 Feb 2008 at 12:09 pm

    @Jan Rychter

    that’s the whole point of using a language like python or ruby… there IS NO COMPILING NEEDED. no one is suggesting they are faster than compiled languages.

  87. Prime Factorisation | self.collect(&:code) WordPress 2.5 on 06 Apr 2008 at 10:34 am

    […] There’s hope though. Apparently, function calling should be a lot faster in Ruby 1.9 […]

  88. Diego Viola PARAGUAY Linux Mozilla Firefox 3.0b5 on 06 Apr 2008 at 11:06 pm

    Ruby rocks.

    can’t wait for 2.0 ;-)

  89. Hodak FINLAND Windows XP Mozilla Firefox 2.0.0.11 on 08 Apr 2008 at 6:27 am

    Very glad to see so much valuable comments.

  90. bogdan ROMANIA Windows XP Mozilla Firefox 2.0.0.14 on 05 May 2008 at 1:10 pm

    Unfortunately I do not see the huge improvement.
    I have compiled ruby 1.8.6 and the ruby 1.9 (from ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.gz), ran the same piece of code.
    1.8.6 took 83 seconds, while 1.9 took 75 or so.
    While it may have improved a little, I do not see any spectacular improvement.

  91. bogdan ROMANIA Windows XP Mozilla Firefox 2.0.0.14 on 05 May 2008 at 1:24 pm

    Umm, ignore the above post :P
    Apparently the link created to the new ruby did not work as intended and I was testing the same version of ruby :D
    No wonder the results were rather similar

Trackback URI | Comments RSS

Leave a Reply