0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一探究竟Java 8的Stream API性能

汽車玩家 ? 來(lái)源:今日頭條 ? 作者:Java的小本家 ? 2020-05-04 14:20 ? 次閱讀

Stream Performance

已經(jīng)對(duì) Stream API 的用法鼓吹夠多了,用起簡(jiǎn)潔直觀,但性能到底怎么樣呢?會(huì)不會(huì)有很高的性能損失?

本節(jié)我們對(duì) Stream API 的性能一探究竟。

為保證測(cè)試結(jié)果真實(shí)可信,我們將 JVM 運(yùn)行在-server模式下,測(cè)試數(shù)據(jù)在 GB 量級(jí),測(cè)試機(jī)器采用常見的商用服務(wù)器,配置如下:

一探究竟Java 8的Stream API性能

測(cè)試方法和測(cè)試數(shù)據(jù)

性能測(cè)試并不是容易的事,Java 性能測(cè)試更費(fèi)勁,因?yàn)樘摂M機(jī)對(duì)性能的影響很大,JVM 對(duì)性能的影響有兩方面:

GC 的影響。GC 的行為是 Java 中很不好控制的一塊,為增加確定性,我們手動(dòng)指定使用 CMS 收集器,并使用 10GB 固定大小的堆內(nèi)存。具體到 JVM 參數(shù)就是-XX:+UseConcMarkSweepGC-Xms10G-Xmx10G

JIT(Just-In-Time) 即時(shí)編譯技術(shù)。即時(shí)編譯技術(shù)會(huì)將熱點(diǎn)代碼在 JVM 運(yùn)行的過程中編譯成本地代碼,測(cè)試時(shí)我們會(huì)先對(duì)程序預(yù)熱,觸發(fā)對(duì)測(cè)試函數(shù)的即時(shí)編譯。相關(guān)的 JVM 參數(shù)是-XX:CompileThreshold=10000。

Stream 并行執(zhí)行時(shí)用到ForkJoinPool.commonPool()得到的線程池,為控制并行度我們使用 Linux 的taskset命令指定 JVM 可用的核數(shù)。

測(cè)試數(shù)據(jù)由程序隨機(jī)生成。為防止一次測(cè)試帶來(lái)的抖動(dòng),測(cè)試 4 次求出平均時(shí)間作為運(yùn)行時(shí)間。

實(shí)驗(yàn)一 基本類型迭代

測(cè)試內(nèi)容:找出整型數(shù)組中的最小值。對(duì)比 for 循環(huán)外部迭代和 Stream API 內(nèi)部迭代性能。

測(cè)試程序 IntTest,測(cè)試結(jié)果如下圖:

一探究竟Java 8的Stream API性能

圖中展示的是 for 循環(huán)外部迭代耗時(shí)為基準(zhǔn)的時(shí)間比值。分析如下:

對(duì)于基本類型 Stream 串行迭代的性能開銷明顯高于外部迭代開銷(兩倍);

Stream 并行迭代的性能比串行迭代和外部迭代都好。

并行迭代性能跟可利用的核數(shù)有關(guān),上圖中的并行迭代使用了全部 12 個(gè)核,為考察使用核數(shù)對(duì)性能的影響,我們專門測(cè)試了不同核數(shù)下的 Stream 并行迭代效果:

一探究竟Java 8的Stream API性能


分析,對(duì)于基本類型:

使用 Stream 并行 API 在單核情況下性能很差,比 Stream 串行 API 的性能還差;

隨著使用核數(shù)的增加,Stream 并行效果逐漸變好,比使用 for 循環(huán)外部迭代的性能還好。

以上兩個(gè)測(cè)試說明,對(duì)于基本類型的簡(jiǎn)單迭代,Stream 串行迭代性能更差,但多核情況下 Stream 迭代時(shí)性能較好。

實(shí)驗(yàn)二 對(duì)象迭代

再來(lái)看對(duì)象的迭代效果。

測(cè)試內(nèi)容:找出字符串列表中最小的元素(自然順序),對(duì)比 for 循環(huán)外部迭代和 Stream API 內(nèi)部迭代性能。

測(cè)試程序 StringTest,測(cè)試結(jié)果如下圖:

一探究竟Java 8的Stream API性能


結(jié)果分析如下:

對(duì)于對(duì)象類型 Stream 串行迭代的性能開銷仍然高于外部迭代開銷(1.5 倍),但差距沒有基本類型那么大。

Stream 并行迭代的性能比串行迭代和外部迭代都好。

再來(lái)單獨(dú)考察 Stream 并行迭代效果:

一探究竟Java 8的Stream API性能

分析,對(duì)于對(duì)象類型:

使用 Stream 并行 API 在單核情況下性能比 for 循環(huán)外部迭代差;

隨著使用核數(shù)的增加,Stream 并行效果逐漸變好,多核帶來(lái)的效果明顯。

以上兩個(gè)測(cè)試說明,對(duì)于對(duì)象類型的簡(jiǎn)單迭代,Stream 串行迭代性能更差,但多核情況下 Stream 迭代時(shí)性能較好。

實(shí)驗(yàn)三 復(fù)雜對(duì)象歸約

從實(shí)驗(yàn)一、二的結(jié)果來(lái)看,Stream 串行執(zhí)行的效果都比外部迭代差(很多),是不是說明 Stream 真的不行了?先別下結(jié)論,我們?cè)賮?lái)考察一下更復(fù)雜的操作。

測(cè)試內(nèi)容:給定訂單列表,統(tǒng)計(jì)每個(gè)用戶的總交易額。對(duì)比使用外部迭代手動(dòng)實(shí)現(xiàn)和 Stream API 之間的性能。

我們將訂單簡(jiǎn)化為構(gòu)成的元組,并用Order對(duì)象來(lái)表示。測(cè)試程序 ReductionTest,測(cè)試結(jié)果如下圖:

一探究竟Java 8的Stream API性能

分析,對(duì)于復(fù)雜的歸約操作:

Stream API 的性能普遍好于外部手動(dòng)迭代,并行 Stream 效果更佳;

再來(lái)考察并行度對(duì)并行效果的影響,測(cè)試結(jié)果如下:

一探究竟Java 8的Stream API性能

分析,對(duì)于復(fù)雜的歸約操作:

使用 Stream 并行歸約在單核情況下性能比串行歸約以及手動(dòng)歸約都要差,簡(jiǎn)單說就是最差的;

隨著使用核數(shù)的增加,Stream 并行效果逐漸變好,多核帶來(lái)的效果明顯。

以上兩個(gè)實(shí)驗(yàn)說明,對(duì)于復(fù)雜的歸約操作,Stream 串行歸約效果好于手動(dòng)歸約,在多核情況下,并行歸約效果更佳。我們有理由相信,對(duì)于其他復(fù)雜的操作,Stream API 也能表現(xiàn)出相似的性能表現(xiàn)。

結(jié)論

上述三個(gè)實(shí)驗(yàn)的結(jié)果可以總結(jié)如下:

對(duì)于簡(jiǎn)單操作,比如最簡(jiǎn)單的遍歷,Stream 串行 API 性能明顯差于顯示迭代,但并行的 Stream API 能夠發(fā)揮多核特性。

對(duì)于復(fù)雜操作,Stream 串行 API 性能可以和手動(dòng)實(shí)現(xiàn)的效果匹敵,在并行執(zhí)行時(shí) Stream API 效果遠(yuǎn)超手動(dòng)實(shí)現(xiàn)。

所以,如果出于性能考慮,

對(duì)于簡(jiǎn)單操作推薦使用外部迭代手動(dòng)實(shí)現(xiàn),

對(duì)于復(fù)雜操作,推薦使用 Stream API,

在多核情況下,推薦使用并行 Stream API 來(lái)發(fā)揮多核優(yōu)勢(shì),

單核情況下不建議使用并行 Stream API。

如果出于代碼簡(jiǎn)潔性考慮,使用 Stream API 能夠?qū)懗龈痰拇a。即使是從性能方面說,盡可能的使用 Stream API 也另外一個(gè)優(yōu)勢(shì),那就是只要 Java Stream 類庫(kù)做了升級(jí)優(yōu)化,代碼不用做任何修改就能享受到升級(jí)帶來(lái)的好處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2946

    瀏覽量

    104370
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1465

    瀏覽量

    61677
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    超高頻讀寫器究竟是什么,能做什么?文讀懂!

    在物聯(lián)網(wǎng)技術(shù)日新月異的今天,超高頻讀寫器作為射頻識(shí)別(RFID)技術(shù)的重要組成部分,正逐漸滲透到我們生活的各個(gè)領(lǐng)域。那么,超高頻讀寫器究竟是什么?它又能做些什么呢?本文將帶您一探究竟。、超高頻
    的頭像 發(fā)表于 10-23 14:41 ?25次閱讀
    超高頻讀寫器<b class='flag-5'>究竟</b>是什么,能做什么?<b class='flag-5'>一</b>文讀懂!

    插座也有顯示屏?快來(lái)一探究竟

    顯示屏智能插座,通過顯示屏實(shí)時(shí)監(jiān)控與可視化展示、智能定時(shí)與提醒、靈活操作與安全保障、節(jié)能環(huán)保,具備高智能化水平,改變用電方式,成為數(shù)字化和智能化時(shí)代的重要橋梁。
    的頭像 發(fā)表于 09-02 15:31 ?200次閱讀
    插座也有顯示屏?快來(lái)<b class='flag-5'>一探究竟</b>!

    揭秘耐壓儀的電流之謎:直流還是交流?

    在電氣設(shè)備的世界里,耐壓儀是個(gè)重要的角色,它負(fù)責(zé)檢驗(yàn)設(shè)備的絕緣性能是否能夠承受規(guī)定的電壓考驗(yàn)。然而,關(guān)于耐壓儀輸出的是直流(DC)還是交流(AC)的問題,卻鮮為人知。今天,我們就來(lái)揭開這神秘的面紗,
    的頭像 發(fā)表于 04-11 08:50 ?709次閱讀
    揭秘耐壓儀的電流之謎:直流還是交流?

    5.5G,多出來(lái)的0.5G又是啥?為什么不直接邁向6G時(shí)代?

    5.5G成為通信行業(yè)2024年開年的大焦點(diǎn)。提到5.5G,多出來(lái)的0.5G又是啥?為什么不直接邁向6G時(shí)代?今天我們一探究竟!
    的頭像 發(fā)表于 04-03 09:40 ?609次閱讀

    OpenVINO? Java API應(yīng)用RT-DETR做目標(biāo)檢測(cè)器實(shí)戰(zhàn)

    本文將從零開始詳細(xì)介紹環(huán)境搭建的完整步驟,我們基于英特爾開發(fā)套件AIxBoard為硬件基礎(chǔ)實(shí)現(xiàn)了Java在Ubuntu 22.04系統(tǒng)上成功使用OpenVINO? Java API,并且成功運(yùn)行了RT-DETR實(shí)現(xiàn)實(shí)時(shí)端到端目標(biāo)
    的頭像 發(fā)表于 03-18 15:04 ?698次閱讀
    OpenVINO? <b class='flag-5'>Java</b> <b class='flag-5'>API</b>應(yīng)用RT-DETR做目標(biāo)檢測(cè)器實(shí)戰(zhàn)

    環(huán)形光源讓圖像質(zhì)量瞬間提升,一探究竟

    光源對(duì)機(jī)器視覺檢測(cè)系統(tǒng)的性能起著重要作用,精確的光學(xué)結(jié)構(gòu)設(shè)計(jì)可以提高捕獲圖像的質(zhì)量,準(zhǔn)確地分離目標(biāo)和背景信息,不充足的光線會(huì)使捕捉到的圖像無(wú)法滿足需求,針對(duì)不同的檢測(cè)對(duì)象,不同的形狀光源應(yīng)運(yùn)而生
    的頭像 發(fā)表于 02-24 08:33 ?1160次閱讀
    環(huán)形光源讓圖像質(zhì)量瞬間提升,<b class='flag-5'>一探究竟</b>!

    原子級(jí)量子芯片如何制造的?

    ,常見的量子計(jì)算芯片中,無(wú)論是超導(dǎo)、離子阱,還是光子芯片,都是肉眼可見的。而原子級(jí)量子集成電路,則需要通過掃描隧道顯微鏡等工具才能一探究竟
    的頭像 發(fā)表于 12-21 09:58 ?812次閱讀
    原子級(jí)量子芯片如何制造的?

    在SpinalHDL里在頂層鍵優(yōu)化Stream/Flow代碼生成

    ? ? 在SpinalHDL里在頂層鍵優(yōu)化代碼中Stream/Flow代碼生成的payload,fragment。 難看的代碼 ? ????來(lái)看段代碼: ? import
    的頭像 發(fā)表于 12-14 09:05 ?610次閱讀

    NVMe SSD性能影響因素一探究竟(下)

    IO Pattern會(huì)對(duì)SSD的性能產(chǎn)生嚴(yán)重影響,主要表現(xiàn)在如下幾個(gè)方面
    的頭像 發(fā)表于 12-09 11:38 ?1417次閱讀
    NVMe SSD<b class='flag-5'>性能</b>影響因素<b class='flag-5'>一探究竟</b>(下)

    生成式AI技術(shù)的應(yīng)用前景

    生成式 AI(人工智能)與我們熟知的 AI 有何不同?這篇文章將為我們一探究竟
    的頭像 發(fā)表于 11-29 12:20 ?1215次閱讀

    簡(jiǎn)單了解Java的新特性

    Java 8Java 20,Java 已經(jīng)走過了漫長(zhǎng)的道路,自 Java 8 以來(lái),
    的頭像 發(fā)表于 11-23 16:38 ?979次閱讀
    簡(jiǎn)單了解<b class='flag-5'>Java</b>的新特性

    java內(nèi)存溢出排查方法

    過程中常見的問題之,可能導(dǎo)致應(yīng)用程序崩潰、性能下降甚至系統(tǒng)崩潰。在本文中,將詳細(xì)介紹如何排查和解決Java內(nèi)存溢出問題。 、什么是Java
    的頭像 發(fā)表于 11-23 14:46 ?2867次閱讀

    AD8231諧波畸變性能究竟在怎樣個(gè)指標(biāo)呢?

    沒有給諧波畸變相關(guān)指標(biāo),不知道是設(shè)計(jì)問題還是芯片本身問題,AD8231諧波畸變性能究竟在怎樣個(gè)指標(biāo)呢?
    發(fā)表于 11-23 08:04

    java對(duì)clob類型數(shù)據(jù)怎么處理

    處理CLOB類型數(shù)據(jù)在Java中是項(xiàng)非常常見和重要的任務(wù)。CLOB(Character Large Object)是種用于存儲(chǔ)大量字符數(shù)據(jù)的數(shù)據(jù)類型,通常用于存儲(chǔ)大型文本文檔、XML文檔
    的頭像 發(fā)表于 11-21 10:30 ?2128次閱讀

    api網(wǎng)關(guān) kong 教程入門

    統(tǒng)權(quán)限控制、接口請(qǐng)求訪問日志統(tǒng)計(jì) 安全,是保護(hù)內(nèi)部服務(wù)而設(shè)計(jì)的道屏障 開源-最大好處 當(dāng)然也有個(gè)很大的缺點(diǎn),api-gw很可能成為性能
    的頭像 發(fā)表于 11-10 11:39 ?653次閱讀
    <b class='flag-5'>api</b>網(wǎng)關(guān) kong 教程入門