Java性能:For-eaching与Streaming
在for循環(huán)中向上或向下計數(shù)是最有效的迭代方式嗎? 有時答案既不是。 閱讀這篇文章,了解不同迭代品種的影響。
迭代性能
關(guān)于如何以高性能進(jìn)行迭代有很多觀點(diǎn)。 Java中的傳統(tǒng)迭代方式是一個for循環(huán),該循環(huán)從零開始,然后計數(shù)到一些預(yù)定義的數(shù)字:
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循環(huán),該循環(huán)以預(yù)定的非負(fù)值開始,然后遞減計數(shù)。 這在JDK本身中非常普遍,例如在String類中。 這是通過遞減而不是遞增來解決先前問題的示例。
@Benchmark public int forDown() {int sum = 0;for (int i = ITERATIONS; i-- > 0;) {sum += i;}return sum; }我認(rèn)為,這樣做的理由是,檢查值與零的關(guān)系可能比測試值與任何其他任意值的關(guān)系更有效。 實(shí)際上,我所知道的所有CPU都有機(jī)器碼指令,可以檢查給定值與零的關(guān)系。 另一個想法是,上面給出的遞減計數(shù)習(xí)慣似乎只檢查一次循環(huán)變量(它同時檢查值,然后減小它),而不是頂部的常規(guī)示例。 我懷疑這對當(dāng)今高效的JIT編譯器影響很小或沒有影響,后者將能夠像優(yōu)化第二個迭代一樣優(yōu)化第一個迭代。 當(dāng)代碼在解釋模式下運(yùn)行時可能會產(chǎn)生影響,但是本文中未對此進(jìn)行檢查。
另一種方法是使用
IntStream看起來像這樣:
如果大型迭代需要更高的性能,則只需在流中添加.parallel()運(yùn)算符就可以使流并行變得相對容易。 本文未對此進(jìn)行檢查。
Graal VM下的性能
在我的筆記本電腦(MacBook Pro,2015年中,2.2 GHz Intel Core i7)上的GraalVM(rc-11,以及GraallVM附帶的新C2編譯器)下運(yùn)行這些測試可以得出以下結(jié)果:
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對于流解決方案是最快的解決方案(盡管誤差在誤差范圍內(nèi)),這可能會讓某些人感到意外。
在上一篇文章中 ,我介紹了與傳統(tǒng)命令式代碼相比,流和聲明式編程在代碼度量方面的一些優(yōu)勢。 我尚未測試過冷代碼段的性能(即,在JIT啟動之前)。
聰明的數(shù)學(xué)
根據(jù)數(shù)學(xué),我們記得從零開始的連續(xù)數(shù)字的總和為N *(N + 1)/ 2,其中N是序列中的最高數(shù)字。 運(yùn)行此基準(zhǔn)測試:
@Benchmark public int math() {return ITERATIONS * (ITERATIONS + 1) / 2; }使我們的性能比以前的實(shí)現(xiàn)提高了1000倍以上:
Benchmark Mode Cnt Score Error Units ForBenchmark.math thrpt 5 395561077.984 ± 11138012.141 ops/s迭代次數(shù)越多,收益越大。 聰明有時會勝過蠻力。
超快速數(shù)據(jù)流
使用Speedment HyperStream,可以從數(shù)據(jù)庫中獲得類似的性能。 在HyperStream上信息 。
結(jié)論
在某些常用的硬件/ JVM上,無論我們在for循環(huán)中向上還是向下進(jìn)行迭代都沒有關(guān)系。 較新的JVM能夠優(yōu)化流迭代,因此與for循環(huán)相比,它們具有同等甚至更好的性能。
在我看來,與for循環(huán)相比,流代碼通常更具可讀性,因此,我相信流在某些將來可能是事實(shí)上的迭代發(fā)明。
使用Speedment HyperStream可以高性能地流傳輸數(shù)據(jù)庫內(nèi)容。
翻譯自: https://www.javacodegeeks.com/2019/09/java-performance-for-eaching-vs-streaming.html
總結(jié)
以上是生活随笔為你收集整理的Java性能:For-eaching与Streaming的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux包(linux包下载)
- 下一篇: ddos攻击端口是什么(ddos攻击用的