Ruby vs Java: Why world is going to end faster with Java?

I have tested recursive method execution speed with classic example of Honoi Tower.

First in Java than JRuby and Ruby with different no. of plates:

package com.example;

public class Hanoi {

  public static void main(String[] args) {      
    int [] plates = {25, 26, 27, 28, 29, 30, 31, 32};
    for(int i = 0; i < plates.length; i++){
        long start = System.currentTimeMillis();
        doTowers(plates[i], 'A', 'B', 'C');
        System.out.println(System.currentTimeMillis() - start);
    }
  }

  public static void doTowers(int topN, char from, char inter, char to) {
    if (topN == 1) {
      //NOP
    } else {
      doTowers(topN - 1, from, to, inter);
      doTowers(topN - 1, inter, from, to);
    }
  }

}

And results are:

Java(millis)   JRuby(sec)   Ruby(sec)    Ruby(sec)   Ruby(sec)   
java 7         jruby-1.7.9  jruby-1.7.9  ruby-2.1.3  ruby-2.1.3 {tailcall_optimization: true}

364            0.269        3.395        6.160       5.515
380            0.321        6.288        12.401      11.082
1349           1.173        13.462       25.497      22.661
2328           1.25         25.714       50.223      44.494
4674           4.73         51.159       101.825     89.22
4995           5.014        103.252      200.308     177.034
18633          18.637       208.356      411.667     357.561
19978          20.927       421.86       805.138     711.872

Looks like running on java and jruby has the same performance.

  • Is it all about JVM? Or does ruby uses only single core of machine?
  • What is the reason for this nonlinear performance loss in Ruby?
  • What is wrong with ruby 2?
  • EDITED

    Added results of Ruby 2.1.3 with { tailcall_optimization: true }. As you can see now it faster then with default false option.

    And another question :

  • Why Ruby code runs times faster on jruby (which currently loads ruby 1.9) than on ruby 2.1.3? Does ruby code compiles as well and runs on jvm?
  • The Ruby and JRuby implementetion are below:

    class Hanoi
    
      def do_towers(top_n, from, inter, to)
        if top_n == 1
          #NOP
        else
          do_towers top_n - 1, from, to, inter
          do_towers top_n - 1, inter, from, to
        end
      end
    end
    
    [25, 26, 27, 28, 29, 30, 31, 32].each do |plate|
      start = Time.now
      HanoiRb.new.do_towers plate, 'A', 'B', 'C'
      puts Time.now - start
    end
    

    JRuby:

    include Java
    $CLASSPATH << 'lib'
    
    Hanoi = JavaUtilities.get_proxy_class('com.example.Hanoi')
    
    [25, 26, 27, 28, 29, 30, 31, 32].each do |plate|
      start = Time.now
      Hanoi.doTowers(plate, 'A'.to_java.toCharArray[0], 'B'.to_java.toCharArray[0], 'C'.to_java.toCharArray[0])
      puts Time.now - start
    end
    

    Is it all about JVM?

    that is what you results suggest. The JVM does heavily optimise the code.

    Or does ruby use only single core of machine?

    Your Java program appears to only use one core as well, so that wouldn't matter.

    What is the reason for this nonlinear performance loose in Ruby?

    The performance in Ruby looks linear with the amount of work required to move all the plates. The Java ones are more surprising.

    The JVM doesn't do tail call optimisation so it would be interesting if you did this in code.

    链接地址: http://www.djcxy.com/p/24088.html

    上一篇: 是否有一个Python等价于在Perl中解引用?

    下一篇: Ruby vs Java:为什么Java会让世界变得更快?