java - Java 中的流比原生 for 循环慢得多 - 为什么?
问题描述
据我了解,流比传统的旧编程更快。
但是,当我运行以下代码时,结果是我没想到的。
public class Application {
public static void main(String[] args) {
long startTime = System.nanoTime();
int[] a = { 1, 2, 3, 4 };
int m = Arrays.stream(a).reduce(Integer.MIN_VALUE, Math::max);
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println(totalTime);
}
}
输出为:22857304
public class Application {
public static void main(String[] args) {
long startTime = System.nanoTime();
int[] a = { 1, 2, 3, 4 };
int e = a.length;
int m = Integer.MIN_VALUE;
for (int i = 0; i < e; i++)
if (a[i] > m)
m = a[i];
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println(totalTime);
}
}
输出为:1459
请帮我理解为什么流这么慢?
解决方案
完全解释这一点需要很多时间;但是您在这里测试的是“冷”启动,基本上没有太多JIT
,而且一个简单的循环不会像 Stream 解决方案那样分配对象 - 因此时间要少得多。Streams 有一个可以运行的基础设施——这需要一段时间来“加热”以提高性能。
代码的这些部分也不等价,就像您正在使用的一样Math::max
,在一个普通的>
。您可以反复测试此代码并查看结果,但即便如此,您也应该使用为微基准量身定制的工具,我知道JMH
(并且Caliper
来自谷歌 - 但我只相信第一个)。
C1
使用 JMH,您可以完全不使用 JIT、仅编译器或其他一些设置来测试这些方法C2
,对于某些设置的示例,请参阅此答案
推荐阅读
- javascript - Zoom blur effect in CSS or Javascript on text
- shell - 检查字符串值的数组条目(主要是语法错误)
- windows - TF r2.3 Windows 上的错误地址构建问题
- typescript - 将对象转换为与我在 Typescript 中的接口相同的类型
- nextflow - Nextflow - 如何避免使用“加入”或类似运算符在两个或多个通道中输入文件的随机样本 ID?
- angular - 我不明白为什么它不进入 for 循环,有什么想法吗?
- git - 如何与 master 保持最新的 Git 分支
- javascript - 下一个js在使用children时向下传递props
- opencv - 有没有类似 findHomography 和 warpPerspective 的函数不使用透视?
- r - ggplot2 geom_function 可以跨 arg 值进行刻面吗?