生成data数组的时间问题

来源:2-9 测试算法性能

hhx2233

2022-10-13 14:41:08

问题描述:

生成data数组,当数组长度同样为10000000时,两种情况中生成data数组所用的时间不一样

第一种情况: 直接生成,时间为1.60s
图片描述
第二种情况: 在生成10000000长度的 数组2 之前,先生成了一个1000000长度的数组1,数组1时间为0.01s,数组2时间为0.35s
图片描述

问题:

同样是生成一个相同长度的数组,为什么时间反而不一样?

代码:

ArrayGenerator数组构造类 和 LinearSearch线性查找类

public class ArrayGenerator {
    private ArrayGenerator() { }
    public static Integer[] generateOrderedArray(int n) {
        Integer[] arr = new Integer[n];
        for (int i = 0; i < n; i++)
            arr[i] = i;
        return arr;
    }
}

public class LinearSearch {
    private LinearSearch() {}
    public static <E> int search(E[] data, E target) {
        for (int i = 0; i < data.length; i++)
            if (data[i].equals(target))
                return i;
        return -1;
    }
}

第一种情况,测试类1

public class Test {
    public static void main(String[] args) {
        int n = 10000000;
        long startTime1 = System.nanoTime();
        Integer[] data = ArrayGenerator.generateOrderedArray(n);
        long endTime1 = System.nanoTime();

        long startTime2 = System.nanoTime();
        for(int k=0;k<10;k++)
            LinearSearch.search(data, n);
        long endTime2 = System.nanoTime();

        //初始化data数组用的时间
        double initTime = (endTime1 - startTime1) / 1000000000.0;
        //search方法用的时间
        double time = (endTime2 - startTime2) / 1000000000.0;
        System.out.println("init time = " + initTime + "s");
        System.out.println("n=" + n + ",10000 runs:"+time+"s");
    }
}

第二中情况,测试类2

public class Main {

    public static void main(String[] args) {
        int[] dataSize = {1000000, 10000000};
        for(int n : dataSize){
            long startTime1 = System.nanoTime();
            Integer[] data = ArrayGenerator.generateOrderedArray(n);
            long endTime1 = System.nanoTime();

            long startTime2 = System.nanoTime();
            for(int k=0;k<10;k++)
                LinearSearch.search(data, n);
            long endTime2 = System.nanoTime();

            //初始化data数组用的时间
            double initTime = (endTime1 - startTime1) / 1000000000.0;
            //search方法用的时间
            double time = (endTime2 - startTime2) / 1000000000.0;
            System.out.println("init time = " + initTime + "s");
            System.out.println("n=" + n + ",10000 runs:"+time+"s");
        }

    }

}

写回答

1回答

liuyubobobo

2022-10-13

简单来说,内存分配不是零成本的。数组越大,在内存中寻找一块连续的空间越难,在一些情况下,操作系统要调整一下内存空间的分布,才能完成内存的分配。


也正是因为这个原因,我们的计时不包括“准备测试用例”的时间,可以更精准的反应算法本身的性能。同时,课程后续你也将看到,在一些算法和数据结构中,如果绕不开 new 操作,尽量减少 new 操作将得到性能的优化(在归并排序中将会有具体的例子。)在链表一章中,我也专门写了一篇文章介绍相关的内容。


继续加油!:)

3
hhx2233
hp>谢谢bobo老师

h022-10-13
共1条回复

算法与数据结构

波波老师5年集大成之作,算法与数据结构系统学习,考试、面试、竞赛通用

2610 学习 · 1087 问题

查看课程