【发布时间】:2014-03-09 17:56:19
【问题描述】:
我运行了两个测试用例(多次),似乎迭代地将值添加到我的列表中比使用 addAll 更快
String[] rawArgs = new String[]{"one", "two", "three", "four", "five"};
// More efficient - 894 ns
List<String> list = new ArrayList<>();
for (String s : rawArgs) {
list.add(s);
}
// Less efficient - 1340 ns
List<String> list = new ArrayList<>();
list.addAll(Arrays.asList(rawArgs));
我通过我的 IDE 以及其他人得到注释,后一种方式是将数组转换为该数据结构的“正确”方式。但如果它实际上比第一个慢,有什么优势(一些模糊的类型安全性?),我应该出于什么原因使用第二个?
编辑 - 代码基准测试:
JVM预热,先重新创建主类对象:
public static void main(String[] args) {
Internet test;
for (int i = 0; i < 15; i++) {
test = new Internet(); // JVM warmup
}
test = new Internet();
test.printOutput();
}
我只是在操作的两端取系统nanotime:
start = System.nanoTime();
/* function */
end = System.nanoTime();
result = end - start;
在测试用例中,每个开始/结束都有单独的字段,并在运行后计算结果(JVM也在运行测试之前通过循环实例来抢先预热)。
编辑 2 - 用更大的集合进行基准测试
经过一些测试(使用 Integer 代替,而不是手写所有数字),看起来更大的集合确实更慢:
100 个号码:
First operation: 18759ns
Second operation: 2680ns
Total operation: 21439ns
【问题讨论】:
-
您如何对代码进行基准测试?
-
会不会是
Arrays.asList返回的额外List对象的创建? -
@RohitJain 我会更新问题
-
好的,现在尝试使用 100 个元素数组,然后使用 1000 个元素(微基准测试是万恶之源)。
-
@rgettman 这是一个潜在的想法,但
Arrays只是将数组包装在一个不可变的静态(假)ArrayList 类中,它不会构造一个全新的列表。
标签: java arrays collections