我正在运行一个模拟河内塔的非常简单的程序。 我打印移动n个(20到30)个磁盘所需的时间。 我看到一种奇怪的模式。移动n(偶数)和n + 1个磁盘所需的时间大致相同。要移动n + 2磁盘,它需要n次磁盘的4倍。 我把程序放在下面。我想当我们有多个递归调用时,在vm中进行了一些优化。 任何人都可以对此有所了解吗?
public class Hanoi {
public static void move(int n) {
if(n > 0) {
move(n-1);
move(n-1);
}
}
public static void main(String[] args) {
int N = 28;
move(12);
for(int n=18; n <= N; n++) {
long start = System.currentTimeMillis();
move(n);
long end = System.currentTimeMillis();
System.out.printf("n=%d t=%d i=%d\n",n, (end-start) , 10);
}
}
}
答案 0 :(得分:1)
这个“问题”? : - )
如果向move
方法添加IO或一些不错的计算,您将看到此行为消失。此外,如果您只进行一次move
递归调用,程序将立即完成。这两种时序异常都归因于Gunner提到的编译器和JIT优化。例如,此版本的move
方法具有更多预期时间:
static int[] pieces = new int[100];
public static void move(int n) {
if (n > 0) {
// random memory operations
pieces[n - 1] = pieces[n];
pieces[n] = pieces[n + 1];
pieces[n + 1] = pieces[n + 2];
move(n - 1);
move(n - 1);
}
}
这是IBM关于tail recursion的一篇有趣的文章。这是关于该主题的另一个blog posting。