在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

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

jf_ro2CN3Fa ? 來(lái)源:稀土掘金 ? 2023-08-09 10:27 ? 次閱讀

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

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

但沒(méi)說(shuō)到為什么。

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

有朋友也提到了這一點(diǎn)。

本文重新開(kāi)始,先問(wèn)是不是,再問(wèn)為什么。

真的更好嗎?

先簡(jiǎn)單寫(xiě)個(gè) 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耗時(shí):"+(System.currentTimeMillis()-startTime1)+"ms");

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

輸出

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

由此可見(jiàn) 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()耗時(shí):"+(System.currentTimeMillis()-startTime)+"ms");

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

此時(shí)輸出變成了。

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

這能證明上面的結(jié)論錯(cuò)誤了嗎?

都不能。

兩種方式都不能證明到底誰(shuí)更快。

使用這種方式在很多場(chǎng)景下是不夠的,某些場(chǎng)景下,JVM 會(huì)對(duì)代碼進(jìn)行 JIT 編譯和內(nèi)聯(lián)優(yōu)化。

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

此時(shí),代碼優(yōu)化前后執(zhí)行的結(jié)果就會(huì)非常大。

基準(zhǔn)測(cè)試是指通過(guò)設(shè)計(jì)科學(xué)的測(cè)試方法、測(cè)試工具和測(cè)試系統(tǒng),實(shí)現(xiàn)對(duì)一類測(cè)試對(duì)象的某項(xiàng)性能指標(biāo)進(jìn)行定量的和可對(duì)比的測(cè)試。

基準(zhǔn)測(cè)試使得被測(cè)試代碼獲得足夠預(yù)熱,讓被測(cè)試代碼得到充分的 JIT 編譯和優(yōu)化。

下面是通過(guò) JMH 做一下基準(zhǔn)測(cè)試,分別測(cè)試集合大小在 100,10000,100000 時(shí)兩種排序方式的性能差異。

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{
//啟動(dòng)基準(zhǔn)測(cè)試
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);
}
}

性能測(cè)試結(jié)果:

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

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

為什么更好?

流本身的損耗

java 的 stream 讓我們可以在應(yīng)用層就可以高效地實(shí)現(xiàn)類似數(shù)據(jù)庫(kù) SQL 的聚合操作了,它可以讓代碼更加簡(jiǎn)潔優(yōu)雅。

但是,假設(shè)我們要對(duì)一個(gè) list 排序,得先把 list 轉(zhuǎn)成 stream 流,排序完成后需要將數(shù)據(jù)收集起來(lái)重新形成 list,這部份額外的開(kāi)銷有多大呢?

我們可以通過(guò)以下代碼來(lái)進(jìn)行基準(zhǔn)測(cè)試。

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;//操作次數(shù)
privatestaticListarrayList;
publicstaticvoidmain(String[]args)throwsRunnerException{
//啟動(dòng)基準(zhǔn)測(cè)試
Optionsopt=newOptionsBuilder()
.include(SortBenchmark3.class.getSimpleName())//要導(dǎo)入的測(cè)試類
.result("SortBenchmark3.json")
.mode(Mode.All)
.resultFormat(ResultFormatType.JSON)
.build();
newRunner(opt).run();//執(zhí)行測(cè)試
}

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

方法 stream 測(cè)試將一個(gè)集合轉(zhuǎn)為流再收集回來(lái)的耗時(shí)。

方法 sort 測(cè)試將一個(gè)集合轉(zhuǎn)為流再排序再收集回來(lái)的全過(guò)程耗時(shí)。

測(cè)試結(jié)果如下:

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

可以發(fā)現(xiàn),集合轉(zhuǎn)為流再收集回來(lái)的過(guò)程,肯定會(huì)耗時(shí),但是它占全過(guò)程的比率并不算高。

因此,這部只能說(shuō)是小部份的原因。

排序過(guò)程

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

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

1 begin方法初始化一個(gè)數(shù)組。

2 accept 接收上游數(shù)據(jù)。

3 end 方法開(kāi)始進(jìn)行排序。

這里第 3 步直接調(diào)用了原生的排序方法,完成排序后,第 4 步,遍歷向下游發(fā)送數(shù)據(jù)。

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

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

這一步我就不做了。

感興趣的朋友可以去測(cè)一下。

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

補(bǔ)充說(shuō)明:

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

絕大多數(shù)場(chǎng)景下,幾百幾千幾萬(wàn)的數(shù)據(jù),開(kāi)心就好,怎么方便怎么用,沒(méi)有必要去計(jì)較這點(diǎn)性能差異。





審核編輯:劉清

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

    關(guān)注

    1

    文章

    782

    瀏覽量

    44886
  • JAVA語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    138

    瀏覽量

    20552
  • JVM
    JVM
    +關(guān)注

    關(guān)注

    0

    文章

    160

    瀏覽量

    12542

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

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    FPGA排序-冒泡排序介紹

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

    排序算法之選擇排序

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

    排序與索引

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

    VHDL中的排序算法怎么實(shí)現(xiàn)?

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

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

    [table][tr][td]聲明:編譯環(huán)境為VS2017 語(yǔ)言:C language針對(duì)對(duì)象:對(duì)n個(gè)數(shù)從小到大進(jìn)行排序(從大到小同理)思路分析:經(jīng)典的bubble sort(冒泡排序)原理類似于
    發(fā)表于 09-12 10:42

    PHP數(shù)組排序

    數(shù)組排序(6個(gè)) sort() - 以升序?qū)?shù)組排序rsort() - 以降序?qū)?shù)組排序 reversal sort)asort() - 根
    發(fā)表于 11-04 07:48

    c語(yǔ)言排序算法之選擇排序

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

    C語(yǔ)言中的排序算法了解

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

    Linux系統(tǒng)中sort排序命令的使用教程

    sort命令的功能是對(duì)文件中的各行進(jìn)行排序sort命令有許多非常實(shí)用的選項(xiàng),這些選項(xiàng)最初是用來(lái)對(duì)數(shù)據(jù)庫(kù)格式的文件內(nèi)容進(jìn)行各種排序操作的。實(shí)際上,
    發(fā)表于 04-02 14:33 ?495次閱讀

    Python中的排序

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

    排序算法merge-sort的基礎(chǔ)知識(shí)

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

    冒泡排序的基本思想

    冒泡排序的英文Bubble Sort,是一種最基礎(chǔ)的交換排序。之所以叫做冒泡排序,因?yàn)槊恳粋€(gè)元素都可以像小氣泡一樣,根據(jù)自身大小一點(diǎn)一點(diǎn)向數(shù)組的一側(cè)移動(dòng)。
    的頭像 發(fā)表于 01-20 11:38 ?6198次閱讀
    冒泡<b class='flag-5'>排序</b>的基本思想

    使用C++ sort函數(shù)對(duì)vector進(jìn)行自定義排序

    今天在學(xué)一些C++ STL容器,看到sort函數(shù)允許自定義排序規(guī)則,小小地實(shí)操了一下。
    的頭像 發(fā)表于 07-22 10:12 ?2100次閱讀

    sort函數(shù)python用法

    sort()函數(shù)是Python中的內(nèi)置函數(shù)之一,用于對(duì)可迭代對(duì)象進(jìn)行排序。可迭代對(duì)象包括列表、元組和字符串等。sort()函數(shù)是一個(gè)靈活而強(qiáng)大的函數(shù),在數(shù)據(jù)分析、算法實(shí)現(xiàn)等方面有著廣泛
    的頭像 發(fā)表于 11-21 15:15 ?2144次閱讀

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

    在linux系統(tǒng)使用過(guò)程中,提供了sort排序命令,支持常用的排序功能。 常用參數(shù) sort命令支持很多參數(shù),常用參數(shù)如下: ? 短參數(shù) 長(zhǎng)參數(shù) 說(shuō)明 -n – number-
    的頭像 發(fā)表于 01-09 10:10 ?848次閱讀
    主站蜘蛛池模板: 亚洲国产成人成上人色 | 亚洲天堂网站 | 久综合色 | 天天操天天干天天操 | 亚欧有色亚欧乱色视频 | 黄色一级毛片在线观看 | 亚洲精品成人a在线观看 | 久久天天躁夜夜躁狠狠85台湾 | 成人在线免费 | 欧美区在线播放 | 在线观看视频网站 | 啪啪日韩| 特级毛片永久久免费观看 | 2021年最热新版天堂资源中文 | 午夜伦理片免费观看在线 | 韩国男女无遮挡高清性视频 | 操操久久 | 午夜激情福利视频 | 日日摸人人看97人人澡 | 双性人皇上被c到哭 | 在线亚洲成人 | 色琪琪一本到影院 | 1024手机看片国产旧版你懂的 | 亚洲国产欧美精品一区二区三区 | 黄色毛片免费 | 国产精品日本亚洲777 | 四虎最新紧急更新地址 | 欧美天天搞 | 天天干天天拍 | 天天躁日日躁狠狠躁中文字幕老牛 | 5x视频在线观看 | 亚洲免费视频在线观看 | 五月天停婷基地 | 美女被免费网站在线视频九色 | 毛片爱做的片 | 免费又黄又硬又大爽日本 | 网站色小妹| aaaa级日本片免费视频 | 亚洲无线码一区在线观看 | 韩彩英三级无删版甜性涩爱 | 国产精品夜夜春夜夜 |