我试图分析将项添加到简单数据结构(可变大小的数组)的复杂性。我通过倍增率实验来做到这一点,即在实验的每次迭代中我将数组大小加倍,然后测量将单个条目添加到数组所花费的时间。
在我的实现中,向数组添加数字需要重新分配所有现有数组条目。因此,人们会认为执行时间应该随着数组中项目数量的增加而增加。
奇怪的是,事实并非如此。
这是一个完整的,最小的例子:
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
),它的行为与预期一致,即它会不断增加。但即使这样,迭代之间的比例也是不一致的,它不应该是(有时执行时间从一次迭代加倍到下一次迭代,有时则几乎翻两倍)。
有没有人有想法为什么会这样?它不应该不断增加?感谢。