与“ for”循环相比,为什么Java流的性能会因工作量较大而下降?

Dav*_*arr 9 java benchmarking java-stream jmh

我之前有一个有关解释JMH输出的问题,大多数人都回答了该问题,但是我用另一个相关问题更新了该问题,但最好将其作为一个单独的问题。

这是原始问题:验证简单的for / lambda比较的JMH测量

我的问题与“工作”特定级别的流性能有关。以下是上一个问题的摘录结果,说明了我想知道的事情:

Benchmark                                            Mode  Cnt          Score         Error  Units
MyBenchmark.shortLengthConstantSizeFor              thrpt  200  132278188.475 ± 1132184.820  ops/s
MyBenchmark.shortLengthConstantSizeLambda           thrpt  200   18750818.019 ±  171239.562  ops/s
MyBenchmark.mediumLengthConstantSizeFor             thrpt  200   55447999.297 ±  277442.812  ops/s
MyBenchmark.mediumLengthConstantSizeLambda          thrpt  200   15925281.039 ±   65707.093  ops/s
MyBenchmark.longerLengthConstantSizeFor             thrpt  200    3551842.518 ±   42612.744  ops/s
MyBenchmark.longerLengthConstantSizeLambda          thrpt  200    2791292.093 ±   12207.302  ops/s
MyBenchmark.longLengthConstantSizeFor               thrpt  200       2984.554 ±      57.557  ops/s
MyBenchmark.longLengthConstantSizeLambda            thrpt  200        331.741 ±       2.196  ops/s
Run Code Online (Sandbox Code Playgroud)

我期望随着测试从较短的列表转移到较长的列表,流测试的性能应接近“ for”测试的性能。

我看到在“简短”列表中,流性能是“ for”性能的14%。对于中型列表,该比例为29%。对于较长的列表,该比例为78%。到目前为止,趋势是我所期望的。但是,对于长名单来说,它是11%。由于某种原因,与“ for”相比,列表大小为300k(而不是300)导致流的性能下降。

我想知道是否有人可以证实这样的结果,以及他们是否对为什么会发生有任何想法。

我正在使用Java 8的Win7笔记本电脑上运行它。

Vla*_*ciu 1

与“for 循环”相比,流对于 Java 来说是一个相当新的补充,而且 JIT 编译器并没有像对数组或集合上的循环那样对它们进行任何复杂的优化。