Ruby vs Java:为什么用Java世界会结束得更快?
我已经用递归的经典示例测试了递归方法的执行速度 在Java中,首先是JRuby和Ruby,具有不同数量的板: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++){
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上运行具有相同的性能
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