2

我正在使用ArrayList并尝试new object在开始时添加已准备好记录ArrayList的预填充。ArrayList3000000

据我所知,它将在第一个索引处添加新对象并将下面的所有记录移动到它们之前的位置。每次我将新对象添加到该数组列表时都会发生这种情况。意味着执行时间应该相同(可能会发生很小的变化)。

但是当我添加新记录时,它显示 0 和某个时间 15。

这是我的程序

package com.rais;

import java.util.ArrayList;
import java.util.List;

public class ArrayListTest {

    public static List<String> arrList = new ArrayList<String>();
    static {
        for (int i = 0; i < 3000000; i++) {
            arrList.add("Hello"+i);
        }
    }


    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {

            long startTime = System.currentTimeMillis();

            arrList.add(0,"Rais"+i);

            long endTime = System.currentTimeMillis();
            System.out.println("Total execution time ="+(endTime-startTime));


        }
       }

    }

这是该程序的输出。

Total execution time =0
Total execution time =0
Total execution time =15
Total execution time =0
Total execution time =0

我很困惑为什么它显示 0 。它应该每次显示 15 或接近 15,但不应显示 0。

4

4 回答 4

4

问题可能出在您的测量方式上,来自currentTimeMillis();

以毫秒为单位返回当前时间。请注意,虽然返回值的时间单位是毫秒,但值的粒度取决于底层操作系统,可能更大。例如,许多操作系统以几十毫秒为单位测量时间。

换句话说,如果 currentTimeMillis 在您的系统上具有接近 15 毫秒的粒度,您将得到 0 或 15 毫秒,这取决于开始时间,即使操作总是花费相同的时间,也会稍微随机。

于 2013-08-11T07:08:15.103 回答
1

我无法解释您看到的结果,但是我怀疑它们至少部分是由您编写的简单的基准测试代码引起的。

高质量的基准测试代码运行数百或数千次迭代,并且对重新编译和运行时优化导致的性能变化很敏感。一般来说System.nanoTime()也用于这些计算。

请参阅IBM 的这篇优秀文章,该文章解释了如何以稳健的方式进行基准测试。本文最后介绍了一个可用于根据最佳实践执行基准测试的框架。

于 2013-08-11T07:06:23.977 回答
1

正如其他答案中提到的,这可能是时钟粒度的问题。您可以使用以下代码检查是否是这种情况:

public static void main(String[] args) {
    try {
        for (int i = 0; i < 30; i++) {

            long startTimeMillis = System.currentTimeMillis();
            long startTimeNanos = System.nanoTime();

            Thread.sleep(11);

            long endTimeMillis = System.currentTimeMillis();
            long endTimeNanos = System.nanoTime();
            System.out.println("Total execution time ="
                + (endTimeMillis-startTimeMillis)+" ms / "
                + (endTimeNanos-startTimeNanos)+" ns");
        }

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

另一种(不太可能)的可能性是 ArrayList 中的数组已达到容量,并且正在扩展(被更大的数组替换)。

于 2013-08-11T13:20:37.143 回答
0

您没有得到准确时间的原因很可能是因为 currentTimeMillis() 不够精确,无法测量它。循环 10000 个并计时,看看你得到了什么。添加到 ArrayList 可能需要微秒,而不是毫秒(在通常情况下)。您看到的 15 毫秒可能是由于垃圾收集或其他原因造成的延迟 - 但无论如何,您的采样太小而无法获得准确的结果。

于 2013-08-11T07:05:57.973 回答