日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

為什么list.sort()比Stream().sorted()更快?

來源: 責編: 時間:2023-09-18 21:41:46 334觀看
導讀看到一個評論,里面提到了list.sort()和list.strem().sorted()排序的差異。說到list.sort()排序比stream().sorted()排序性能更好。但沒說到為什么。有朋友也提到了這一點。本文重新開始,先問是不是,再問為什么。真的更好

看到一個評論,里面提到了list.sort()和list.strem().sorted()排序的差異。XNw28資訊網——每日最新資訊28at.com

說到list.sort()排序比stream().sorted()排序性能更好。XNw28資訊網——每日最新資訊28at.com

但沒說到為什么。XNw28資訊網——每日最新資訊28at.com

XNw28資訊網——每日最新資訊28at.com

有朋友也提到了這一點。XNw28資訊網——每日最新資訊28at.com

本文重新開始,先問是不是,再問為什么。XNw28資訊網——每日最新資訊28at.com

真的更好嗎?

先簡單寫個 demo。XNw28資訊網——每日最新資訊28at.com

List<Integer> userList = new ArrayList<>();    Random rand = new Random();    for (int i = 0; i < 10000 ; i++) {        userList.add(rand.nextInt(1000));    }    List<Integer> userList2 = new ArrayList<>();    userList2.addAll(userList);    Long startTime1 = System.currentTimeMillis();    userList2.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());    System.out.println("stream.sort耗時:"+(System.currentTimeMillis() - startTime1)+"ms");    Long startTime = System.currentTimeMillis();    userList.sort(Comparator.comparing(Integer::intValue));    System.out.println("List.sort()耗時:"+(System.currentTimeMillis()-startTime)+"ms");

輸出:XNw28資訊網——每日最新資訊28at.com

stream.sort耗時:62msList.sort()耗時:7ms

由此可見 list 原生排序性能更好。XNw28資訊網——每日最新資訊28at.com

能證明嗎?XNw28資訊網——每日最新資訊28at.com

不一定吧。XNw28資訊網——每日最新資訊28at.com

再把 demo 變換一下,先輸出stream.sort。XNw28資訊網——每日最新資訊28at.com

List<Integer> userList = new ArrayList<>();Random rand = new Random();for (int i = 0; i < 10000 ; i++) {    userList.add(rand.nextInt(1000));}List<Integer> userList2 = new ArrayList<>();userList2.addAll(userList);Long startTime = System.currentTimeMillis();userList.sort(Comparator.comparing(Integer::intValue));System.out.println("List.sort()耗時:"+(System.currentTimeMillis()-startTime)+"ms");Long startTime1 = System.currentTimeMillis();userList2.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());System.out.println("stream.sort耗時:"+(System.currentTimeMillis() - startTime1)+"ms");

此時輸出變成了:XNw28資訊網——每日最新資訊28at.com

List.sort()耗時:68msstream.sort耗時:13ms

這能證明上面的結論錯誤了嗎?XNw28資訊網——每日最新資訊28at.com

都不能。XNw28資訊網——每日最新資訊28at.com

兩種方式都不能證明到底誰更快。XNw28資訊網——每日最新資訊28at.com

使用這種方式在很多場景下是不夠的,某些場景下,JVM 會對代碼進行 JIT 編譯和內聯優化。XNw28資訊網——每日最新資訊28at.com

Long startTime = System.currentTimeMillis();...System.currentTimeMillis() - startTime

此時,代碼優化前后執行的結果就會非常大。XNw28資訊網——每日最新資訊28at.com

基準測試是指通過設計科學的測試方法、測試工具和測試系統,實現對一類測試對象的某項性能指標進行定量的和可對比的測試。XNw28資訊網——每日最新資訊28at.com

基準測試使得被測試代碼獲得足夠預熱,讓被測試代碼得到充分的 JIT 編譯和優化。XNw28資訊網——每日最新資訊28at.com

下面是通過 JMH 做一下基準測試,分別測試集合大小在 100,10000,100000 時兩種排序方式的性能差異。XNw28資訊網——每日最新資訊28at.com

import org.openjdk.jmh.annotations.*;import org.openjdk.jmh.infra.Blackhole;import org.openjdk.jmh.results.format.ResultFormatType;import org.openjdk.jmh.runner.Runner;import org.openjdk.jmh.runner.RunnerException;import org.openjdk.jmh.runner.options.Options;import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.*;import java.util.concurrent.ThreadLocalRandom;import java.util.concurrent.TimeUnit;import java.util.stream.Collectors;@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)@Warmup(iterations = 2, time = 1)@Measurement(iterations = 5, time = 5)@Fork(1)@State(Scope.Thread)public class SortBenchmark {    @Param(value = {"100", "10000", "100000"})    private int operationSize;     private static List<Integer> arrayList;    public static void main(String[] args) throws RunnerException {        // 啟動基準測試        Options opt = new OptionsBuilder()            .include(SortBenchmark.class.getSimpleName())             .result("SortBenchmark.json")            .mode(Mode.All)            .resultFormat(ResultFormatType.JSON)            .build();        new Runner(opt).run();     }    @Setup    public void init() {        arrayList = new ArrayList<>();        Random random = new Random();        for (int i = 0; i < operationSize; i++) {            arrayList.add(random.nextInt(10000));        }    }    @Benchmark    public void sort(Blackhole blackhole) {        arrayList.sort(Comparator.comparing(e -> e));        blackhole.consume(arrayList);    }    @Benchmark    public void streamSorted(Blackhole blackhole) {        arrayList = arrayList.stream().sorted(Comparator.comparing(e -> e)).collect(Collectors.toList());        blackhole.consume(arrayList);    }}

性能測試結果:XNw28資訊網——每日最新資訊28at.com

XNw28資訊網——每日最新資訊28at.com

可以看到,list.sort()效率確實比stream().sorted()要好。XNw28資訊網——每日最新資訊28at.com

為什么更好?XNw28資訊網——每日最新資訊28at.com

流本身的損耗

java 的 stream 讓我們可以在應用層就可以高效地實現類似數據庫 SQL 的聚合操作了,它可以讓代碼更加簡潔優雅。XNw28資訊網——每日最新資訊28at.com

但是,假設我們要對一個 list 排序,得先把 list 轉成 stream 流,排序完成后需要將數據收集起來重新形成 list,這部份額外的開銷有多大呢?XNw28資訊網——每日最新資訊28at.com

我們可以通過以下代碼來進行基準測試:XNw28資訊網——每日最新資訊28at.com

import org.openjdk.jmh.annotations.*;import org.openjdk.jmh.infra.Blackhole;import org.openjdk.jmh.results.format.ResultFormatType;import org.openjdk.jmh.runner.Runner;import org.openjdk.jmh.runner.RunnerException;import org.openjdk.jmh.runner.options.Options;import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.ArrayList;import java.util.Comparator;import java.util.List;import java.util.Random;import java.util.concurrent.TimeUnit;import java.util.stream.Collectors;@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)@Warmup(iterations = 2, time = 1)@Measurement(iterations = 5, time = 5)@Fork(1)@State(Scope.Thread)public class SortBenchmark3 {    @Param(value = {"100", "10000"})    private int operationSize; // 操作次數    private static List<Integer> arrayList;    public static void main(String[] args) throws RunnerException {        // 啟動基準測試        Options opt = new OptionsBuilder()            .include(SortBenchmark3.class.getSimpleName()) // 要導入的測試類            .result("SortBenchmark3.json")            .mode(Mode.All)            .resultFormat(ResultFormatType.JSON)            .build();        new Runner(opt).run(); // 執行測試    }    @Setup    public void init() {        // 啟動執行事件        arrayList = new ArrayList<>();        Random random = new Random();        for (int i = 0; i < operationSize; i++) {            arrayList.add(random.nextInt(10000));        }    }    @Benchmark    public void stream(Blackhole blackhole) {        arrayList.stream().collect(Collectors.toList());        blackhole.consume(arrayList);    }    @Benchmark    public void sort(Blackhole blackhole) {        arrayList.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());        blackhole.consume(arrayList);    }}

方法 stream 測試將一個集合轉為流再收集回來的耗時。XNw28資訊網——每日最新資訊28at.com

方法 sort 測試將一個集合轉為流再排序再收集回來的全過程耗時。XNw28資訊網——每日最新資訊28at.com

測試結果如下:XNw28資訊網——每日最新資訊28at.com

XNw28資訊網——每日最新資訊28at.com

可以發現,集合轉為流再收集回來的過程,肯定會耗時,但是它占全過程的比率并不算高。XNw28資訊網——每日最新資訊28at.com

因此,這部只能說是小部份的原因。XNw28資訊網——每日最新資訊28at.com

排序過程

我們可以通過以下源碼很直觀的看到。XNw28資訊網——每日最新資訊28at.com

XNw28資訊網——每日最新資訊28at.com

  • 1 begin方法初始化一個數組。
  • 2 accept 接收上游數據。
  • 3 end 方法開始進行排序。

這里第 3 步直接調用了原生的排序方法,完成排序后,第 4 步,遍歷向下游發送數據。XNw28資訊網——每日最新資訊28at.com

所以通過源碼,我們也能很明顯地看到,stream()排序所需時間肯定是 > 原生排序時間。XNw28資訊網——每日最新資訊28at.com

只不過,這里要量化地搞明白,到底多出了多少,這里得去編譯 jdk 源碼,在第 3 步前后將時間打印出來。XNw28資訊網——每日最新資訊28at.com

這一步我就不做了。XNw28資訊網——每日最新資訊28at.com

感興趣的朋友可以去測一下。XNw28資訊網——每日最新資訊28at.com

不過我覺得這兩點也能很好地回答,為什么list.sort()比Stream().sorted()更快。XNw28資訊網——每日最新資訊28at.com

補充說明:XNw28資訊網——每日最新資訊28at.com

  • 本文說的 stream() 流指的是串行流,而不是并行流。
  • 絕大多數場景下,幾百幾千幾萬的數據,開心就好,怎么方便怎么用,沒有必要去計較這點性能差異。

本文鏈接:http://www.www897cc.com/showinfo-26-10468-0.html為什么list.sort()比Stream().sorted()更快?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C++中表達式的必要性

下一篇: 分布式事務原理及解決方案

標簽:
  • 熱門焦點
  • 6月安卓手機性價比榜:Note 12 Turbo斷層式碾壓

    6月份有一個618,雖然這是京東周年慶的日子,但別的電商也都不約而同的跟進了,反正促銷沒壞處,廠商和用戶都能滿意。618期間一些產品也出現了歷史低價,那么各個價位段的產品性價比
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標系統提供非預期的輸入并監視異常結果來發現軟件漏洞的方法??梢杂脕戆l現應用程序、操作系統和網絡協議等中的漏洞或
  • 使用Webdriver-manager解決瀏覽器與驅動不匹配所帶來自動化無法執行的問題

    1、前言在我們使用 Selenium 進行 UI 自動化測試時,常常會因為瀏覽器驅動與瀏覽器版本不匹配,而導致自動化測試無法執行,需要手動去下載對應的驅動版本,并替換原有的驅動,可能還
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 大廠卷向扁平化

    來源:新熵作者丨南枝 編輯丨月見大廠職級不香了。俗話說,兵無常勢,水無常形,互聯網企業調整職級體系并不稀奇。7月13日,淘寶天貓集團啟動了近年來最大的人力制度改革,目前已形成一
  • ESG的面子與里子

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之三伏大幕拉起,各地高溫預警不絕,但處于厄爾尼諾大&ldquo;烤&rdquo;之下的除了眾生,還有各大企業發布的ESG報告。ESG是&ldquo;環境保
  • 華為和江淮汽車合作開發百萬元問界MPV?雙方回應來了

    8月1日消息,郭明錤今天在社交平臺發文稱,華為正在和江淮汽車合作,開發售價在100萬元的問界MPV,預計在2024年第2季度量產,銷量目標為上市首年交付5萬輛。
  • 三星Galaxy Z Fold5今日亮相:厚度縮減但仍略顯厚重

    據官方此前宣布,三星將于7月26日也就是今天在韓國首爾舉辦Unpacked活動,屆時將帶來帶來包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy
  • 蘋果140W USB-C充電器:采用氮化鎵技術

    據10 月 30 日 9to5 Mac 消息報道,當蘋果推出新的 MacBook Pro 2021 時,該公司還推出了新的 140W USB-C 充電器,附贈在 MacBook Pro 16 英寸機型的盒子里,也支
Top 主站蜘蛛池模板: 西充县| 九龙县| 宁明县| 永定县| 大连市| 西青区| 石门县| 尉犁县| 疏附县| 青龙| 大悟县| 宁远县| 景泰县| 芜湖县| 新密市| 老河口市| 东乡| 枝江市| 股票| 凌海市| 宜良县| 根河市| 舟曲县| 宝坻区| 梁平县| 吉首市| 威远县| 文成县| 邯郸市| 广宁县| 盐源县| 天镇县| 耿马| 瓦房店市| 太湖县| 防城港市| 体育| 无为县| 梨树县| 楚雄市| 蒙山县|