龙岩做网站开发哪家厉害,企业网站酷站,深圳微信网站设计,网站建设 国际 深圳在for循环中向上或向下计数是最有效的迭代方式吗#xff1f; 有时答案既不是。 阅读这篇文章#xff0c;了解不同迭代品种的影响。 迭代性能 关于如何以高性能进行迭代有很多观点。 Java中的传统迭代方式是一个for循环#xff0c;该循环从零开始#xff0c;然后计数到一些… 在for循环中向上或向下计数是最有效的迭代方式吗 有时答案既不是。 阅读这篇文章了解不同迭代品种的影响。 迭代性能 关于如何以高性能进行迭代有很多观点。 Java中的传统迭代方式是一个for循环该循环从零开始然后计数到一些预定义的数字 private static final int ITERATIONS 10_000;Benchmark
public int forUp() {int sum 0;for (int i 0; i ITERATIONS; i) {sum i;}return sum;
} 有时我们遇到一个for循环该循环以预定的非负值开始然后递减计数。 这在JDK本身中非常普遍例如在String类中。 这是通过递减而不是递增来解决先前问题的示例。 Benchmark
public int forDown() {int sum 0;for (int i ITERATIONS; i-- 0;) {sum i;}return sum;
} 我认为这样做的理由是检查值与零的关系可能比测试值与任何其他任意值的关系更有效。 实际上我所知道的所有CPU都有机器码指令可以检查给定值与零的关系。 另一个想法是上面给出的递减计数习惯似乎只检查一次循环变量它同时检查值然后减小它而不是顶部的常规示例。 我怀疑这对当今高效的JIT编译器影响很小或没有影响后者将能够像优化第二个迭代一样优化第一个迭代。 当代码在解释模式下运行时可能会产生影响但是本文中未对此进行检查。 另一种方法是使用 IntStream看起来像这样 Benchmark
public int stream() {return IntStream.range(0, ITERATIONS).sum();
} 如果大型迭代需要更高的性能则只需在流中添加.parallel()运算符就可以使流并行变得相对容易。 本文未对此进行检查。 Graal VM下的性能 在我的笔记本电脑MacBook Pro2015年中2.2 GHz Intel Core i7上的GraalVMrc-11以及GraallVM附带的新C2编译器下运行这些测试可以得出以下结果 Benchmark Mode Cnt Score Error Units
ForBenchmark.forDown thrpt 5 311419.166 ± 4201.724 ops/s
ForBenchmark.forUp thrpt 5 309598.916 ± 12998.579 ops/s
ForBenchmark.stream thrpt 5 312360.089 ± 8291.792 ops/s 对于流解决方案是最快的解决方案尽管误差在误差范围内这可能会让某些人感到意外。 在上一篇文章中 我介绍了与传统命令式代码相比流和声明式编程在代码度量方面的一些优势。 我尚未测试过冷代码段的性能即在JIT启动之前。 聪明的数学 根据数学我们记得从零开始的连续数字的总和为N *N 1/ 2其中N是序列中的最高数字。 运行此基准测试 Benchmark
public int math() {return ITERATIONS * (ITERATIONS 1) / 2;
} 使我们的性能比以前的实现提高了1000倍以上 Benchmark Mode Cnt Score Error Units
ForBenchmark.math thrpt 5 395561077.984 ± 11138012.141 ops/s 迭代次数越多收益越大。 聪明有时会胜过蛮力。 超快速数据流 使用Speedment HyperStream可以从数据库中获得类似的性能。 在HyperStream上信息 。 结论 在某些常用的硬件/ JVM上无论我们在for循环中向上还是向下进行迭代都没有关系。 较新的JVM能够优化流迭代因此与for循环相比它们具有同等甚至更好的性能。 在我看来与for循环相比流代码通常更具可读性因此我相信流在某些将来可能是事实上的迭代发明。 使用Speedment HyperStream可以高性能地流传输数据库内容。 翻译自: https://www.javacodegeeks.com/2019/09/java-performance-for-eaching-vs-streaming.html