女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

list.sort()排序比stream().sorted()排序性能更好嗎?

jf_ro2CN3Fa ? 來源:稀土掘金 ? 2023-08-09 10:27 ? 次閱讀

看到一個評論,里面提到了list.sort()和list.strem().sorted()排序的差異。

說到list.sort()排序比stream().sorted()排序性能更好。

但沒說到為什么。

d679a17a-3654-11ee-9e74-dac502259ad0.jpg

有朋友也提到了這一點。

本文重新開始,先問是不是,再問為什么。

真的更好嗎?

先簡單寫個 demo。

ListuserList=newArrayList<>();
Randomrand=newRandom();
for(inti=0;iuserList2=newArrayList<>();
userList2.addAll(userList);

LongstartTime1=System.currentTimeMillis();
userList2.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
System.out.println("stream.sort耗時:"+(System.currentTimeMillis()-startTime1)+"ms");

LongstartTime=System.currentTimeMillis();
userList.sort(Comparator.comparing(Integer::intValue));
System.out.println("List.sort()耗時:"+(System.currentTimeMillis()-startTime)+"ms");

輸出

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

由此可見 list 原生排序性能更好。

能證明嗎?

不一定吧。

再把 demo 變換一下,先輸出stream.sort。

ListuserList=newArrayList<>();
Randomrand=newRandom();
for(inti=0;iuserList2=newArrayList<>();
userList2.addAll(userList);

LongstartTime=System.currentTimeMillis();
userList.sort(Comparator.comparing(Integer::intValue));
System.out.println("List.sort()耗時:"+(System.currentTimeMillis()-startTime)+"ms");

LongstartTime1=System.currentTimeMillis();
userList2.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
System.out.println("stream.sort耗時:"+(System.currentTimeMillis()-startTime1)+"ms");

此時輸出變成了。

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

這能證明上面的結論錯誤了嗎?

都不能。

兩種方式都不能證明到底誰更快。

使用這種方式在很多場景下是不夠的,某些場景下,JVM 會對代碼進行 JIT 編譯和內聯優化。

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

此時,代碼優化前后執行的結果就會非常大。

基準測試是指通過設計科學的測試方法、測試工具和測試系統,實現對一類測試對象的某項性能指標進行定量的和可對比的測試。

基準測試使得被測試代碼獲得足夠預熱,讓被測試代碼得到充分的 JIT 編譯和優化。

下面是通過 JMH 做一下基準測試,分別測試集合大小在 100,10000,100000 時兩種排序方式的性能差異。

importorg.openjdk.jmh.annotations.*;
importorg.openjdk.jmh.infra.Blackhole;
importorg.openjdk.jmh.results.format.ResultFormatType;
importorg.openjdk.jmh.runner.Runner;
importorg.openjdk.jmh.runner.RunnerException;
importorg.openjdk.jmh.runner.options.Options;
importorg.openjdk.jmh.runner.options.OptionsBuilder;

importjava.util.*;
importjava.util.concurrent.ThreadLocalRandom;
importjava.util.concurrent.TimeUnit;
importjava.util.stream.Collectors;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations=2,time=1)
@Measurement(iterations=5,time=5)
@Fork(1)
@State(Scope.Thread)
publicclassSortBenchmark{
@Param(value={"100","10000","100000"})
privateintoperationSize;
privatestaticListarrayList;
publicstaticvoidmain(String[]args)throwsRunnerException{
//啟動基準測試
Optionsopt=newOptionsBuilder()
.include(SortBenchmark.class.getSimpleName())
.result("SortBenchmark.json")
.mode(Mode.All)
.resultFormat(ResultFormatType.JSON)
.build();
newRunner(opt).run();
}
@Setup
publicvoidinit(){
arrayList=newArrayList<>();
Randomrandom=newRandom();
for(inti=0;ie));
blackhole.consume(arrayList);
}
@Benchmark
publicvoidstreamSorted(Blackholeblackhole){
arrayList=arrayList.stream().sorted(Comparator.comparing(e->e)).collect(Collectors.toList());
blackhole.consume(arrayList);
}
}

性能測試結果:

d6919d0c-3654-11ee-9e74-dac502259ad0.jpg

可以看到,list.sort()效率確實比stream().sorted()要好。

為什么更好?

流本身的損耗

java 的 stream 讓我們可以在應用層就可以高效地實現類似數據庫 SQL 的聚合操作了,它可以讓代碼更加簡潔優雅。

但是,假設我們要對一個 list 排序,得先把 list 轉成 stream 流,排序完成后需要將數據收集起來重新形成 list,這部份額外的開銷有多大呢?

我們可以通過以下代碼來進行基準測試。

importorg.openjdk.jmh.annotations.*;
importorg.openjdk.jmh.infra.Blackhole;
importorg.openjdk.jmh.results.format.ResultFormatType;
importorg.openjdk.jmh.runner.Runner;
importorg.openjdk.jmh.runner.RunnerException;
importorg.openjdk.jmh.runner.options.Options;
importorg.openjdk.jmh.runner.options.OptionsBuilder;

importjava.util.ArrayList;
importjava.util.Comparator;
importjava.util.List;
importjava.util.Random;
importjava.util.concurrent.TimeUnit;
importjava.util.stream.Collectors;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations=2,time=1)
@Measurement(iterations=5,time=5)
@Fork(1)
@State(Scope.Thread)
publicclassSortBenchmark3{
@Param(value={"100","10000"})
privateintoperationSize;//操作次數
privatestaticListarrayList;
publicstaticvoidmain(String[]args)throwsRunnerException{
//啟動基準測試
Optionsopt=newOptionsBuilder()
.include(SortBenchmark3.class.getSimpleName())//要導入的測試類
.result("SortBenchmark3.json")
.mode(Mode.All)
.resultFormat(ResultFormatType.JSON)
.build();
newRunner(opt).run();//執行測試
}

@Setup
publicvoidinit(){
//啟動執行事件
arrayList=newArrayList<>();
Randomrandom=newRandom();
for(inti=0;i

方法 stream 測試將一個集合轉為流再收集回來的耗時。

方法 sort 測試將一個集合轉為流再排序再收集回來的全過程耗時。

測試結果如下:

d6a99132-3654-11ee-9e74-dac502259ad0.jpg

可以發現,集合轉為流再收集回來的過程,肯定會耗時,但是它占全過程的比率并不算高。

因此,這部只能說是小部份的原因。

排序過程

我們可以通過以下源碼很直觀的看到。

d6bc1794-3654-11ee-9e74-dac502259ad0.jpg

1 begin方法初始化一個數組。

2 accept 接收上游數據。

3 end 方法開始進行排序。

這里第 3 步直接調用了原生的排序方法,完成排序后,第 4 步,遍歷向下游發送數據。

所以通過源碼,我們也能很明顯地看到,stream()排序所需時間肯定是 > 原生排序時間。

只不過,這里要量化地搞明白,到底多出了多少,這里得去編譯 jdk 源碼,在第 3 步前后將時間打印出來。

這一步我就不做了。

感興趣的朋友可以去測一下。

不過我覺得這兩點也能很好地回答,為什么list.sort()比Stream().sorted()更快。

補充說明:

本文說的 stream() 流指的是串行流,而不是并行流。

絕大多數場景下,幾百幾千幾萬的數據,開心就好,怎么方便怎么用,沒有必要去計較這點性能差異。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • SQL
    SQL
    +關注

    關注

    1

    文章

    780

    瀏覽量

    44800
  • JAVA語言
    +關注

    關注

    0

    文章

    138

    瀏覽量

    20509
  • JVM
    JVM
    +關注

    關注

    0

    文章

    160

    瀏覽量

    12516

原文標題:為什么list.sort()比Stream().sorted()更快?

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    FPGA排序-冒泡排序介紹

    排序算法是圖像處理中經常使用一種算法,常見的排序算法有插入排序、希爾排序、選擇排序、冒泡排序、歸
    發表于 07-17 10:12 ?1291次閱讀
    FPGA<b class='flag-5'>排序</b>-冒泡<b class='flag-5'>排序</b>介紹

    排序算法之選擇排序

    選擇排序: (Selection sort)是一種簡單直觀的排序算法,也是一種不穩定的排序方法。 選擇排序的原理: 一組無序待排數組,做升序
    的頭像 發表于 09-25 16:30 ?2543次閱讀
    <b class='flag-5'>排序</b>算法之選擇<b class='flag-5'>排序</b>

    排序與索引

    記錄順序。排序后生成一個新表,新表的記錄按新的物理順序排列。 命令格式:SORT TO <新文件名> ON <字段名1> [/A|/D] [/C
    發表于 03-10 15:58

    VHDL中的排序算法怎么實現?

    be able to read the numbers from the BRAM, sort them and write the sorted "list" in another
    發表于 03-29 13:44

    冒泡排序法三部曲の冒泡排序原理版(一)

    [table][tr][td]聲明:編譯環境為VS2017 語言:C language針對對象:對n個數從小到大進行排序(從大到小同理)思路分析:經典的bubble sort(冒泡排序)原理類似于
    發表于 09-12 10:42

    PHP數組排序

    數組排序(6個) sort() - 以升序對數組排序rsort() - 以降序對數組排序 reversal sort)asort() - 根
    發表于 11-04 07:48

    c語言排序算法之選擇排序

    法就是"先選后排"。假定待排序數字序列均為整數,且共有NUM個,大小隨機排列,存放在list[NUM]中。 ? ? ? ?首先假定list[0]為序列中最小的數字,再依次拿它與list
    發表于 11-16 10:25 ?3520次閱讀
    c語言<b class='flag-5'>排序</b>算法之選擇<b class='flag-5'>排序</b>法

    C語言中的排序算法了解

    選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起
    的頭像 發表于 11-12 14:52 ?2852次閱讀

    Linux系統中sort排序命令的使用教程

    sort命令的功能是對文件中的各行進行排序sort命令有許多非常實用的選項,這些選項最初是用來對數據庫格式的文件內容進行各種排序操作的。實際上,
    發表于 04-02 14:33 ?483次閱讀

    Python中的排序

    另外一種排序方法是 sorted ,此方法不是原地排序,以第一個值進行排序,同樣也是默認升序排序
    的頭像 發表于 09-07 16:25 ?2364次閱讀
    Python中的<b class='flag-5'>排序</b>

    排序算法merge-sort的基礎知識

    本文介紹、解釋、評估和實現了排序算法merge-sort 。本文的目的是為您提供有關合并排序算法的可靠背景信息,該算法是更復雜算法的基礎知識。
    的頭像 發表于 04-07 17:54 ?2857次閱讀
    <b class='flag-5'>排序</b>算法merge-<b class='flag-5'>sort</b>的基礎知識

    冒泡排序的基本思想

    冒泡排序的英文Bubble Sort,是一種最基礎的交換排序。之所以叫做冒泡排序,因為每一個元素都可以像小氣泡一樣,根據自身大小一點一點向數組的一側移動。
    的頭像 發表于 01-20 11:38 ?6161次閱讀
    冒泡<b class='flag-5'>排序</b>的基本思想

    使用C++ sort函數對vector進行自定義排序

    今天在學一些C++ STL容器,看到sort函數允許自定義排序規則,小小地實操了一下。
    的頭像 發表于 07-22 10:12 ?2049次閱讀

    sort函數python用法

    sort()函數是Python中的內置函數之一,用于對可迭代對象進行排序。可迭代對象包括列表、元組和字符串等。sort()函數是一個靈活而強大的函數,在數據分析、算法實現等方面有著廣泛
    的頭像 發表于 11-21 15:15 ?2049次閱讀

    詳解Linux sort命令之掌握排序技巧與實用案例

    在linux系統使用過程中,提供了sort排序命令,支持常用的排序功能。 常用參數 sort命令支持很多參數,常用參數如下: ? 短參數 長參數 說明 -n – number-
    的頭像 發表于 01-09 10:10 ?793次閱讀