运行河内塔时的奇怪行为

时间:2010-09-15 14:18:53

标签: java

我正在运行一个模拟河内塔的非常简单的程序。 我打印移动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);
        }
    }
}

1 个答案:

答案 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