我有一个围绕3483对象的ArrayList,它准备在数据库中合并。
当我使用lambda表达式时 - 它需要85122毫秒。
但是for(Obj o : list)
只需要25毫秒。为什么Java8需要3404倍的时间?
List<CIBSubjectData> list1 = .....
list1.forEach(data ->
merge(data)
);
for (CIBSubjectData data : list1) {
merge(data);
}
答案 0 :(得分:3)
我相信你没有使用合适的微基准设置。您正在比较bytecode instrumentation framework
(用于在运行时生成lambda字节码的ASM)+ lambda execution time
与execution time of the loop
的预热。
检查performance-difference-between-java-8-lambdas-and-anonymous-inner-classes和链接文档的答案。链接的文档深入了解了幕后的处理。
修改提供一个小片段来演示上述内容。
public class Warmup {
static int dummy;
static void merge(String s) {
dummy += s.length();
dummy++;
dummy -= s.length();
}
public static void main(String[] args) throws IOException {
List<String> list1 = new ArrayList<>();
Random rand = new Random(1);
for (int i = 0; i < 100_000; i++) {
list1.add(Long.toString(rand.nextLong()));
}
// this will boostrap the bytecode instrumentation
// Stream.of("foo".toCharArray()).forEach(System.out::println);
long start = System.nanoTime();
list1.forEach(data -> merge(data));
long end = System.nanoTime();
System.out.printf("duration: %d%n", end - start);
System.out.println(dummy);
}
}
如果您在发布时运行代码,则我的机器上的打印持续时间为
duration: 71694425
如果取消注释行Stream.of(...
(第一次只使用字节码检测框架),则打印持续时间为
duration: 7516086
这只是初次运行的10%左右。
注意只是要明确。不要使用如上所述的基准测试。请查看jmh以了解此类要求。