gpt4 book ai didi

java - 对 Java8 Stream 性能感到困惑

转载 作者:搜寻专家 更新时间:2023-10-31 19:27:45 24 4
gpt4 key购买 nike

我不明白为什么要使用 Stream api 对同一个数组进行多次迭代结果是这样的表现!

请看下面的代码。

public class WhyIsDifferent {

public static void main(String[] args) {

int[] values = getArray();
Iterate(values, 598, 600); // 70 ms
Iterate(values, 200, 202); // 0 ms
Iterate(values, 700, 702); // 0 ms
Iterate(values, 300, 310); // 1 ms
}

public static void Iterate(int[] values, int from, int to) {
long start = System.currentTimeMillis();
IntStream.of(values).filter(i -> i < to && i > from)
.forEach(i ->
System.out.println(i) // do a something
);
System.out.println("Time:" + (System.currentTimeMillis() - start));
}

public static int[] getArray() {
int[] values = new int[1000];
for (int i = 0; i < 1000; i++) {
values[i] = i;
}
return values;
}
}

确定 JVM 优化了代码,但我不知道这是怎么发生的?太棒了!你知道为什么会这样吗?

--

我在 Ubuntu 14.04//Oracle jdk/intel cpu 上测试。

最佳答案

它不是 JIT 编译器。这 70 毫秒中的大部分时间都花在了整个 lambda 子系统的初始化上(该逻辑的入口点可能是 LambdaMetaFactory 类),还有相当一部分时间花在了 lambda Bootstrap 调用上(< em>linkage 阶段,如用户 fge 所述)。看看这个方法,和你的一样,但是所有的步骤都是单独测量的(我使用的是 nanoTime):

public static void Iterate(int[] values, int from, int to) {
long start = System.nanoTime();
final IntPredicate predicate = i -> i < to && i > from;
System.out.println("Predicate lambda creation time:" + NANOSECONDS.toMillis(System.nanoTime() - start));
start = System.nanoTime();
final IntConsumer action = System.out::println;
System.out.println("Action lambda creation time:" + NANOSECONDS.toMillis(System.nanoTime() - start));
start = System.nanoTime();
final IntStream stream = IntStream.of(values).filter(predicate);
System.out.println("Stream creation time:" + NANOSECONDS.toMillis(System.nanoTime() - start));
start = System.nanoTime();
stream.forEach(action);
System.out.println("Stream consumption time:" + NANOSECONDS.toMillis(System.nanoTime() - start));
}

这是我机器上打印的内容:

Predicate lambda creation time:53
Action lambda creation time:2
Stream creation time:2
599
Stream consumption time:1
Predicate lambda creation time:0
Action lambda creation time:0
Stream creation time:0
201
... all timings zero from here on...

您可以看到,第一次调用的全部开销都在 lambda 创建部分(仅在第一次运行时,包括一般初始化和链接),流创建也需要一些时间。在所有情况下,实际流消耗时间为零。

对于当前版本的 HotSpot,这种效果绝对值得您牢记:lambda bootstrap 是一件昂贵的事情。

最后一点:如果您重新排序 lambda 创建语句,您会发现大部分时间都停留在要创建的第一个 lambda 上。这向我们表明,它实际上只是承担大部分初始化成本的 lambda 的第一个整体创建。

关于java - 对 Java8 Stream 性能感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27109944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com