我正在使用ArrayList
并尝试在预先填充new object
ArrayList
条ArrayList
的{{1}}开头添加3000000
。
根据我的知识,它会在第一个索引处添加新对象,并将下面的所有记录移动到之前的位置。每当我将新对象添加到该数组列表时,就会发生这种情况。意味着执行时间应该相同(可能会发生很小的变化)。
但是当我添加新的记录时,它显示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.
答案 0 :(得分:4)
问题可能是您从currentTimeMillis()
的文档中测量的方式;
以毫秒为单位返回当前时间。请注意,虽然返回值的时间单位是毫秒,但值的粒度取决于基础操作系统,可能更大。例如,许多操作系统以几十毫秒为单位测量时间。
换句话说,如果currentTimeMillis在您的系统上具有接近15ms的粒度,那么即使操作总是花费相同的时间,您也将获得0或15ms,稍微随机,具体取决于开始时间。
答案 1 :(得分:1)
我无法解释您看到的结果,但我怀疑它们至少部分是由您编写的简单基准代码引起的。
高质量的基准测试代码可运行数百或数千次迭代,并且由于重新编译和运行时优化而对性能变化很敏感。一般来说,System.nanoTime()
也用于这些计算。
请参阅this excellent article from IBM,了解如何以强大的方式进行基准测试。本文最后提出了一个框架,可用于根据最佳实践执行基准测试。
答案 2 :(得分: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中的数组已达到容量,并且正在扩展(由更大的数组替换)。
答案 3 :(得分:0)
最有可能的原因是你没有得到准确的时间是因为currentTimeMillis()不够精确,不能测量它。做一个10000的循环,然后看看你得到了什么。添加到ArrayList可能需要几微秒,而不是毫秒(通常情况下)。你看到的15ms可能是由于垃圾收集或其他原因造成的延迟 - 但无论如何,你的采样太小而无法获得准确的结果。