我已经使用Honoi Tower的经典示例测试了递归方法执行速度。
首先在Java中比JRuby和Ruby有不同的no。板块:
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具有相同的性能。
EDITED
使用{ tailcall_optimization: true }添加了Ruby 2.1.3的结果。正如您现在所看到的那样,使用默认的false选项会更快。
另一个问题:
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
答案 0 :(得分:3)
这是关于JVM的吗?
这就是你的结果。 JVM大大优化了代码。
或者红宝石只使用单核机器吗?
您的Java程序似乎也只使用一个核心,因此无关紧要。
Ruby中这种非线性性能松散的原因是什么?
Ruby中的性能与移动所有印版所需的工作量呈线性关系。 Java更令人惊讶。
JVM不进行尾调用优化,所以如果你在代码中这样做会很有趣。