双倍率实验中的执行时间不一致。第一次迭代总是比第二次慢。 (实验复杂性分析)

时间:2018-02-18 10:40:04

标签: java time-complexity complexity-theory

我试图分析将项添加到简单数据结构(可变大小的数组)的复杂性。我通过倍增率实验来做到这一点,即在实验的每次迭代中我将数组大小加倍,然后测量将单个条目添加到数组所花费的时间。

在我的实现中,向数组添加数字需要重新分配所有现有数组条目。因此,人们会认为执行时间应该随着数组中项目数量的增加而增加。

奇怪的是,事实并非如此。

这是一个完整的,最小的例子:

public class Experiment {
    int size = 0;
    int[] arr = new int[0];

    public static void main(String[] args) throws Exception {
        int minN = 125;
        int maxN = 128000;
        long start;
        long duration;

        Experiment experiment = new Experiment();

        for(int n=minN; n<=maxN; n+=n) {
            while(experiment.size < n) experiment.add(111);

            start = System.nanoTime();
            experiment.add(111);
            duration = System.nanoTime() - start;

            System.out.println("N: " + n + "\t Execution time: " + duration);
        }
    }

    public void add(int number) throws Exception {
        // Init temporary array with size + 1
        this.size++;
        int[] tmpArr = new int[this.size];

        // Reallocate existing entries
        for(int i=0; i<this.arr.length; i++) tmpArr[i] = this.arr[i];

        // Add new number
        tmpArr[this.size - 1] = number;

        // Replace with temporary array
        this.arr = tmpArr;
    }
}

执行实验时,这是我得到的结果:

N: 125       Execution time: 1799
N: 250       Execution time: 624
N: 500       Execution time: 1133
N: 1000      Execution time: 2161
N: 2000      Execution time: 566
N: 4000      Execution time: 1270
N: 8000      Execution time: 3195
N: 16000     Execution time: 6655
N: 32000     Execution time: 12155
N: 64000     Execution time: 56298
N: 128000    Execution time: 61612

我多次执行实验,并且以下模式始终成立:第一次迭代比第二次迭代花费的时间长得多。在第三次和第四次迭代中,执行时间再次增加。在第五,它再次下降,然后不断增加。

我注意到,如果我在第五次迭代中开始实验(通过设置minN = 2000),它的行为与预期一致,即它会不断增加。但即使这样,迭代之间的比例也是不一致的,它不应该是(有时执行时间从一次迭代加倍到下一次迭代,有时则几乎翻两倍)。

有没有人有想法为什么会这样?它不应该不断增加?感谢。

0 个答案:

没有答案