Ruby -> Lisp translator = much faster Ruby interpreter

Discussion in 'Ruby' started by harsh, May 1, 2006.

  1. harsh

    harsh Guest

    I got bored over the weekend and spent some time working on a very
    basic Ruby to Lisp translator. My goal was to get a basic idea of the
    kind of performance that could be expected from such a thing.

    It's at the point now where this:

    def fib(n)
    if n < 3 then 1 else fib(n-1) + fib(n -2) end

    translates to this:

    ((|self| OBJECT-INSTANCE) |n|)
    (IF (RUBY::TRUEP (RMETH::M-< |n| 3))
    (RMETH::M-+ (RMETH::M-FIB |self| (RMETH::M-- |n| 1))
    (RMETH::M-FIB |self| (RMETH::M-- |n|

    The Lisp version runs pretty quickly on CMUCL. Run times for "fib(32)"
    on my machine are:

    - 0.8 seconds in the translated-to-Lisp version
    - 11.5s for vanilla Ruby 1.8.2
    - 3.8s for YARV 0.4.0/Ruby 1.9.0
    - 3.3s for Python 2.3.5
    - 5.0s for Perl 5.8.4

    It's just a couple days' work, and doesn't yet support much of the
    language (basically just method definitions, instance variables, and
    method calls; and even support them fully). But if there's enough
    interest I'd probably keep working on it, and/or publicly post the
    soure code.
    harsh, May 1, 2006
    1. Advertisements

  2. ha scritto:
    I guess this code is easily translatable in binary even via YARV's
    ruby->C translator and/or ruby2c, it would be nice to see comparisons :)
    interestingly, the PyPy guys have an (outdated) CMUCL backend, so I
    think at least the idea of running $language on a lisp implementation is
    not so strange :)
    It would be interesting to see what you've done, and I wonder if you
    used some of the previous work such as ripper to build the AST or
    ParseTree or metaruby's type inferencer or whatever.
    gabriele renzi, May 1, 2006
    1. Advertisements

  3. harsh

    ts Guest

    h> - 0.8 seconds in the translated-to-Lisp version
    h> - 11.5s for vanilla Ruby 1.8.2
    h> - 3.8s for YARV 0.4.0/Ruby 1.9.0

    Well, if I'm right, yarv actually don't have tail-call optimization
    ts, May 1, 2006
  4. In this case the obvious improvement here is of course to use an
    iterative approach...

    [email protected] ~
    $ ruby bin/fib.rb.txt

    [email protected] ~
    $ cat bin/fib.rb.txt
    def fib(n)
    if n < 3 then 1 else fib(n-1) + fib(n -2) end
    def fibi(n)
    n.times{|i| a = i < 3 ? 1 : a[i-1] + a[i-2]}
    t1 =
    fib 32
    t2 =
    fibi 32
    t3 =
    puts t2-t1, t3-t2

    Is it worth the effort to improve the speed of an inefficient algorithm
    by making it run on a different platform? Or put differently: what kind
    of problems are you trying to solve with this? Or even differently:
    when speed is more important than simplicity, wouldn't you write Lisp,
    Java, C++ etc. in the first place? Personally I'd probably prefer see
    efforts go into optimization of the Ruby runtime (for example detecting
    and improving tail recursion).

    Kind regards

    Robert Klemme, May 1, 2006
  5. I think he already answered that.

    Erik Hollensbe, May 2, 2006
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.