为什么 Ruby 比 Java 慢这么多?

Why is Ruby so much slower than Java?

当我偶然发现 this problem 时,我正在研究 Project Euler 问题。我在 Rails 上写了一个程序,在 Ruby 中正确地解决了它(语言的新手):

class Collatz
 def search
    counter = 0
    storage = 0
    amount = 0
    (1..1000000).each do |i| i += 1
      temp = i
      while temp != 1
        temp = temp & 1 == 1 ? 3 * temp + 1 : temp >> 1
        counter += 1
      end
      if counter > amount
        amount = counter
        storage = i
      end
      counter = 0
    end
    puts storage
  end
end

start = Time.now
collatz = Collatz.new
collatz.search
ending = Time.now
puts "Time: #{ending - start}"

我意识到这花了很长时间,准确地说是 15.185317 秒。 然而,当我尝试 Java 时,时间要短得多:

public class Euler{

    private static void problem() {
        long a;
        int j;
        int max = 0;
        int maxnr = 0;
        for(int i = 1; i < 1000000; i++) {
            a = i;
            j = 1;
            while( a != 1 ) {
                a = ((a & 1) == 1) ? (3 * a + 1) : (a >> 1);
                j++;
            }
            if(j > max) {
                max = j;
                maxnr = i;
            }
        }
        System.out.println(maxnr);
    }

    public static void main(String[] args) {
        long ct = System.currentTimeMillis();
        problem();
        long nt = System.currentTimeMillis() - ct;
        System.out.println(nt);
}

最后这个程序用了769毫秒。我正在为 Ruby 使用 RubyMine,为 Java 使用 Intellij IDEA。我似乎无法弄清楚为什么需要这么长时间,我不确定这是否正常。这个任务似乎并不太难,因为我只是在循环。

你对这个问题的解决很差。它涉及做大量的重复工作。显然,JVM 在优化这种冗余工作方面比 Ruby.

要好得多

但是,如果您要编写一个明确使用以前工作的适当解决方案,您会发现在 Ruby 或 Java 上 运行 并不重要。您可以通过使用数组或映射来存储以前的结果来做到这一点。这种技术也称为动态规划。