日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

java lambda::_基准测试:Java 8 Lambda和流如何使您的代码慢5倍

發(fā)布時(shí)間:2023/12/3 java 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java lambda::_基准测试:Java 8 Lambda和流如何使您的代码慢5倍 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java lambda::

與長(zhǎng)期的實(shí)現(xiàn)相比,Java 8 lambda和流的性能如何?

Lambda表達(dá)式和流在Java 8中受到了熱烈的歡迎。這些是迄今為止很激動(dòng)人心的功能,很長(zhǎng)一段時(shí)間以來(lái),它們就已經(jīng)應(yīng)用到Java中了。 新的語(yǔ)言功能使我們可以在代碼中采用更具功能性的樣式,并且在其中玩耍很有趣。 太有趣了,應(yīng)該是非法的。 然后我們變得可疑 ,并決定對(duì)它們進(jìn)行測(cè)試。

我們已經(jīng)完成了一個(gè)簡(jiǎn)單的任務(wù),即在ArrayList中找到最大值,并測(cè)試了長(zhǎng)期的實(shí)現(xiàn)與Java 8中可用的新方法的對(duì)比。老實(shí)說(shuō),結(jié)果令人驚訝。

Java 8中的命令式與功能式編程

我們喜歡直截了當(dāng),所以讓我們看一下結(jié)果。 對(duì)于此基準(zhǔn),我們創(chuàng)建了一個(gè)ArrayList,為其中填充了100,000個(gè)隨機(jī)整數(shù),并實(shí)現(xiàn)了7種不同的方式來(lái)遍歷所有值以找到最大值。 這些實(shí)現(xiàn)分為兩類(lèi):具有Java 8中引入的新語(yǔ)言功能的功能樣式和具有長(zhǎng)期Java方法的命令式樣式。

這是每種方法花費(fèi)的時(shí)間:

**記錄的最大錯(cuò)誤是parallelStream上的0.042,完整的結(jié)果輸出可在該文章的底部找到

外賣(mài)

  • 哎呀! 使用Java 8提供的任何新方法來(lái)實(shí)現(xiàn)解決方案,都會(huì)使性能下降5倍左右。 有時(shí),使用帶有迭代器的簡(jiǎn)單循環(huán)比將lambda和流混入混合要好。 即使這意味著編寫(xiě)更多的代碼行并跳過(guò)那種甜蜜的語(yǔ)法糖。
  • 使用迭代器或for-each循環(huán)是遍歷ArrayList的最有效方法。 比具有索引int的傳統(tǒng)for循環(huán)好兩倍。
  • 在Java 8方法中,使用并行流被證明更有效。 但是當(dāng)心, 在某些情況下,它實(shí)際上可能會(huì)使您減速。
  • Lambas取代了它們?cè)诹骱蚿arallelStream實(shí)現(xiàn)之間的位置。 令人驚訝的是,它們的實(shí)現(xiàn)基于流API。
  • [編輯]事情并非總是如此:盡管我們想展示在lambda和流中引入錯(cuò)誤有多么容易,但我們收到了很多社區(qū)反饋,要求對(duì)基準(zhǔn)代碼添加更多優(yōu)化并刪除對(duì)它們的裝箱/拆箱。整數(shù)。 包括優(yōu)化在內(nèi)的第二組結(jié)果可在本文的底部獲得。
  • 等一下,我們到底在這里測(cè)試了什么?

    讓我們快速瀏覽一下每種方法,從最快到最慢:

    命令式

    forMaxInteger() –使用簡(jiǎn)單的for循環(huán)和int索引遍歷列表:

    public int forMaxInteger() {int max = Integer.MIN_VALUE;for (int i = 0; i < size; i++) {max = Integer.max(max, integers.get(i));}return max; }

    iteratorMaxInteger() –使用迭代器遍歷列表:

    public int iteratorMaxInteger() {int max = Integer.MIN_VALUE;for (Iterator<Integer> it = integers.iterator(); it.hasNext(); ) {max = Integer.max(max, it.next());}return max; }

    forEachLoopMaxInteger() –丟失迭代器,并使用For-Each循環(huán)遍歷列表(不要誤解為Java 8 forEach):

    public int forEachLoopMaxInteger() {int max = Integer.MIN_VALUE;for (Integer n : integers) {max = Integer.max(max, n);}return max; }

    功能風(fēng)格

    parallelStreamMaxInteger() –在并行模式下使用Java 8流瀏覽列表:

    public int parallelStreamMaxInteger() {Optional<Integer> max = integers.parallelStream().reduce(Integer::max);return max.get(); }

    lambdaMaxInteger() –將lambda表達(dá)式與流一起使用。 甜蜜的一線:

    public int lambdaMaxInteger() {return integers.stream().reduce(Integer.MIN_VALUE, (a, b) -> Integer.max(a, b)); }

    forEachLambdaMaxInteger() –對(duì)于我們的用例,這有點(diǎn)混亂。 新的Java 8 forEach功能可能最令人討厭的是它只能使用最終變量,因此我們?yōu)樽罱K包裝器類(lèi)創(chuàng)建了一些變通方法,該類(lèi)訪問(wèn)我們正在更新的最大值:

    public int forEachLambdaMaxInteger() {final Wrapper wrapper = new Wrapper();wrapper.inner = Integer.MIN_VALUE;integers.forEach(i -> helper(i, wrapper));return wrapper.inner.intValue(); }public static class Wrapper {public Integer inner; }private int helper(int i, Wrapper wrapper) {wrapper.inner = Math.max(i, wrapper.inner);return wrapper.inner; }

    順便說(shuō)一句,如果我們已經(jīng)在談?wù)揻orEach,請(qǐng)查看這個(gè)StackOverflow答案,我們就其某些缺點(diǎn)提供了一些有趣的見(jiàn)解。

    streamMaxInteger() –使用Java 8流瀏覽列表:

    public int streamMaxInteger() {Optional<Integer> max = integers.stream().reduce(Integer::max);return max.get(); }

    優(yōu)化基準(zhǔn)

    遵循本文的反饋意見(jiàn),我們創(chuàng)建了基準(zhǔn)的另一個(gè)版本。 與原始代碼的所有差異都可以在此處查看 。 結(jié)果如下:

    TL; DR:更改摘要

  • 該列表不再可變。
  • forMax2的新方法刪除了字段訪問(wèn)。
  • forEachLambda中的冗余幫助程序功能已修復(fù)。 現(xiàn)在,lambda也正在分配一個(gè)值。 可讀性較低,但速度更快。
  • 自動(dòng)裝箱消除了。 如果您在Eclipse中打開(kāi)項(xiàng)目的自動(dòng)裝箱警告,則舊代碼中有15條警告。
  • 在reduce之前使用mapToInt修復(fù)流代碼。
  • 感謝Patrick Reinhart , Richard Warburton , Yan Bonnel , Sergey Kuksenko , Jeff Maxwell , Henrik Gustafsson以及在Twitter上發(fā)表評(píng)論的每個(gè)人!

    基礎(chǔ)

    為了運(yùn)行此基準(zhǔn),我們使用了JMH,即Java Microbenchmarking Harness。 如果您想了解更多有關(guān)如何在自己的項(xiàng)目中使用它的信息, 請(qǐng)查看這篇文章 ,我們將通過(guò)動(dòng)手示例來(lái)了解它的一些主要功能。

    基準(zhǔn)配置包括2個(gè)JVM分支,5個(gè)預(yù)熱迭代和5個(gè)測(cè)量迭代。 測(cè)試使用Java 8u66和JMH 1.11.2在c3.xlarge Amazon EC2實(shí)例(4個(gè)vCPU,7.5 Mem(GiB),2 x 40 GB SSD存儲(chǔ))上運(yùn)行。 完整的源代碼可在GitHub上找到 ,您可以在此處查看原始結(jié)果輸出。

    話雖這么說(shuō),但有一點(diǎn)免責(zé)聲明:基準(zhǔn)往往非常危險(xiǎn),要正確地制定基準(zhǔn)則非常困難。 雖然我們嘗試以最準(zhǔn)確的方式運(yùn)行它,但始終建議您花一點(diǎn)時(shí)間來(lái)獲取結(jié)果。

    最后的想法

    使用Java 8時(shí),要做的第一件事是嘗試使用lambda表達(dá)式和流。 但是要當(dāng)心:它感覺(jué)真的很好,很甜,所以您可能會(huì)上癮! 我們已經(jīng)看到,堅(jiān)持使用迭代器和for-each循環(huán)的更傳統(tǒng)的Java編程風(fēng)格,明顯優(yōu)于Java 8提供的新實(shí)現(xiàn)。當(dāng)然,情況并非總是如此,但是在這個(gè)非常常見(jiàn)的示例中,它表明可以大約差5倍。 如果它影響系統(tǒng)的核心部分或創(chuàng)建新的瓶頸,這會(huì)變得非常可怕。

    翻譯自: https://www.javacodegeeks.com/2015/11/benchmark-java-8-lambdas-streams-can-make-code-5-times-slower.html

    java lambda::

    總結(jié)

    以上是生活随笔為你收集整理的java lambda::_基准测试:Java 8 Lambda和流如何使您的代码慢5倍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。