Ruby vs Java:为什么世界会因为Java而更快地结束



我已经用河内塔的经典例子测试了递归方法的执行速度。

在Java中比JRuby和Ruby具有不同的盘子编号:

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);
    }
  }
}

结果是:

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

看起来在java和jruby上运行具有相同的性能。

  1. 这一切都与JVM有关吗?还是 ruby 只使用机器的单核?
  2. Ruby 中这种非线性性能损失的原因是什么?
  3. 红宝石 2 有什么问题?

编辑

添加了 Ruby 2.1.3 的结果,其中包含 { tailcall_optimization: true }。正如您现在所看到的,它比默认的 false 选项更快。

还有一个问题

  1. 为什么 Ruby 代码在 jruby(目前加载 ruby 1.9)上的运行速度比在 ruby 2.1.3 上快几倍?Ruby 代码也可以编译并在 jvm 上运行吗?

Ruby 和 JRuby 实现如下:

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

这一切都与JVM有关吗?

这就是你的结果所建议的。 JVM确实对代码进行了大量优化。

还是 Ruby 只使用机器的单核?

您的Java程序似乎也只使用一个内核,因此这无关紧要。

Ruby 中这种非线性性能松散的原因是什么?

Ruby 中的性能看起来与移动所有板所需的工作量成线性关系。 Java的更令人惊讶。

JVM不进行尾部调用优化,因此如果您在代码中执行此操作会很有趣。

相关内容

最新更新