1.为什么流在JDK 9上运行更快
Stream.count()在JDK
8中,实现相当笨拙:它只是迭代整个流,
1L为每个元素添加。
这已在JDK 9
中修复。即使错误报告中提到了SIZED流,新代码也可以改善非大小型流。
如果您替换
.count()为Java 8样式的实现
.mapToLong(e -> 1L).sum(),即使在JDK 9上,它也会再次变慢。
2.为什么天真的循环工作缓慢
当您将所有代码放入
main方法中时,就无法有效地对其进行JIT编译。此方法仅执行一次,它开始在解释器中运行,随后,当JVM检测到热循环时,它会从解释模式切换为即时编译。这称为堆栈上替换(OSR)。
OSR编译通常没有常规编译方法那样优化。我详细解释这个前面,看到这个和这个答案。
如果将内部循环放在单独的方法中,JIT将产生更好的代码:
long solutions = 0; for (Integer p : peter) { solutions += countLargerThan(colin, p); } ... private static int countLargerThan(List<Integer> colin, int p) { int count = 0; for (Integer c : colin) { if (p > c) { count++; } } return count; }在这种情况下,
countLargerThan方法将被正常编译,并且其性能将优于在JDK 8和JDK 9上使用流。



