Ruby vs Java:为什么用Java世界会结束得更快?

Ruby vs Java:为什么用Java世界会结束得更快?,java,ruby,recursion,towers-of-hanoi,Java,Ruby,Recursion,Towers Of Hanoi,我已经用递归的经典示例测试了递归方法的执行速度 在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++){

我已经用递归的经典示例测试了递归方法的执行速度

在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和jruby上运行具有相同的性能

  • 这都是关于JVM的吗?还是ruby只使用机器的单核
  • Ruby中这种非线性性能损失的原因是什么
  • ruby 2有什么问题
  • 已编辑

    添加了Ruby 2.1.3的结果。正如您现在看到的,它比使用默认的false选项更快

    还有另一个问题:

  • 为什么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
    
    包含Java
    $CLASSPATH
    这都是关于JVM的吗

    这就是你的结果。JVM对代码进行了大量优化

    还是ruby只使用机器的单核

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

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


    Ruby的性能与移动所有板所需的工作量呈线性关系。Java版本更令人惊讶


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

    “Ruby中的性能看起来与工作量成线性关系”,但您能否解释一下,与JVM相比,随着工作量的增加,非线性性能损失(动态)会如何?谢谢@SergiiBrytiuk每个额外的板块深度需要两倍的移动,所以你可以期待Ruby所展示的模式。Java one似乎在跳跃,这表明一些“有趣的”性能优化正在发挥作用。@PeterLawrey跳跃是每隔一个增量出现的(如果在日志图上绘制它们的图表,这确实会弹出)。我猜现在的情况是,每次你需要另一个RAM字来适应
    int[]plates
    (在64位机器上,这是每隔一个增量,因为int是32位的),代码就会变慢。例如,n=26需要13个单词,而n=27和n=28需要13个单词(n=27是12.5,但不能有半个单词)。所以有一个从n=26到n=27的跳跃,但不是从n=27到n=28。基本上,Java的速度足够快,这些小的影响是可以测量的。左轴包含日志图上的两个JVM运行时间;右轴为
    天花板(plates.length/2)
    (您需要的字数)。您可以看到这些行似乎或多或少地在一起移动,除了n=28时Java上的一个“亮点”,这可能只是噪音(来自GC、编译、计算机上的其他活动等)。顺便说一下:IBM J9 JVM确实执行尾部调用优化。我根本没有资格回答这个问题,但是,我和另一个程序员的一段磨合以他向我展示这一点而结束,我输掉了一场辩论@谢谢你。Twitter的快乐结局证明了Java的用途。Twitter通过Ruby实现了自己的目标,并加入了新的领域,即Java统治的领域。但我对这个特殊的例子很感兴趣。“世界末日”的标题怎么了?@KyleStrand…当拼图(板块)的最后一步完成时。
    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