for-forEach-stream.forEach三种遍历方法
java8新出的循環方式,在網上有大量的道友說用流的方式效率反而更低了。
大量的結論表明,這種方式只是語法糖(for-forEach-stream三種遍歷方法執行效率比較與選用思考 - ZZY1078689276的專欄 - CSDN博客
https://blog.csdn.net/ZZY1078689276/article/details/79430772)這篇文章一樣的內容看了不止一次,我都不知道誰先寫的。。
不過,耳聽為虛,眼見為實,上代碼親自試驗:
?public static void main(String[] args) {
? ? // 測試源
? ? List<String> sourceList = new ArrayList<>();
? ? for (int i = 0;i<10;i++) {
? ? ? ? sourceList.add("第" + i + "條數據");
? ? }
? ? System.out.println("數據條數:" + sourceList.size());
? ? long a1=System.currentTimeMillis();
? ? for (int i = 0;i < sourceList.size();i++) doSome();
? ? long a2=System.currentTimeMillis();
? ? System.out.println("普通for循環用時:" + (a2-a1));
? ? long b1=System.currentTimeMillis();
? ? for (String t:sourceList) doSome();
? ? long b2=System.currentTimeMillis();
? ? System.out.println("增強for循環用時:" + (b2-b1));
? ? long c1=System.currentTimeMillis();
? ? sourceList.forEach((t)-> doSome());
? ? long c2=System.currentTimeMillis();
? ? System.out.println("forEach循環用時:" + (c2-c1));
?
? ? long d1=System.currentTimeMillis();
? ? sourceList.parallelStream().forEach((t)-> doSome());
? ? long d2=System.currentTimeMillis();
? ? System.out.println("forEach-Stream循環用時:" + (d2-d1));
}
結果如下:
數據條數:10
普通for循環用時:0
增強for循環用時:0
forEach循環用時:43
forEach-Stream循環用時:6?
好吧,數據少了點,不過結果也很明顯了,使用forEach循環耗時最多,流啟動也很耗時。
不過,讓我們把循環次數提升至100W如何?
數據條數:1000000
普通for循環用時:3
增強for循環用時:10
forEach循環用時:46
forEach-Stream循環用時:33
forEach-Stream方式用時增加了,不過forEach用時并沒有明顯增加,再來一次:
數據條數:1000000
普通for循環用時:3
增強for循環用時:7
forEach循環用時:38
forEach-Stream循環用時:31
exm?forEach循環用時反而減少了是什么情況?不過今天我不研究原理,只看結論的話,for循環和增強for循環至少還是比新出的forEach-Stream要強很多的。
但這么一來,難道新功能真的只是語法糖么?
有人問我doSome()做了什么?實際上我什么都沒做,但如果我真的做了什么呢?
比如等待一毫秒?
?private static void doSome() {
? ? try {
? ? ? ? Thread.sleep(1);
? ? } catch (Exception e) {
? ? ? ? e.printStackTrace();
? ? }
}
再來一次:
?數據條數:10000
普通for循環用時:10025
增強for循環用時:10009
forEach循環用時:10067
forEach-Stream循環用時:1567
Duang!!!!!!!
forEach-Stream的效率獲得了碾壓式的勝利!有人說是因為jvm預熱原因,但先且不論預熱的是什么(通常是指啟動時加載的東西),預熱這種一次性的行為怎么可能取得這么大的提升?
于是,讓我們打印一下doSome()的線程
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-6
ForkJoinPool.commonPool-worker-2
main
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-6
main
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-4
ForkJoinPool.commonPool-worker-5
ForkJoinPool.commonPool-worker-7
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-5
main
stream().forEach用的多線程方式,其調用線程池的時候必然會耗費更多的時間。但如果你在循環內要處理的事情很多,或者要循環調用遠程接口/數據庫的時候,無疑極大的提升了效率
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的for-forEach-stream.forEach三种遍历方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stream 的方式遍历(亲测)
- 下一篇: 爱国主义教育(说一说爱国主义教育的简介)