第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 8:Streams vs Collections的性能

Java 8:Streams vs Collections的性能

眼眸繁星 2019-08-30 15:53:40
我是Java 8的新手。我仍然不深入了解API,但我已經(jīng)做了一個小的非正式基準(zhǔn)測試來比較新Streams API與優(yōu)秀舊Collections的性能。測試包括過濾一個列表Integer,并為每個偶數(shù)計算平方根并將其存儲在結(jié)果List中Double。這是代碼:    public static void main(String[] args) {        //Calculating square root of even numbers from 1 to N               int min = 1;        int max = 1000000;        List<Integer> sourceList = new ArrayList<>();        for (int i = min; i < max; i++) {            sourceList.add(i);        }        List<Double> result = new LinkedList<>();        //Collections approach        long t0 = System.nanoTime();        long elapsed = 0;        for (Integer i : sourceList) {            if(i % 2 == 0){                result.add(Math.sqrt(i));            }        }        elapsed = System.nanoTime() - t0;               System.out.printf("Collections: Elapsed time:\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));        //Stream approach        Stream<Integer> stream = sourceList.stream();               t0 = System.nanoTime();        result = stream.filter(i -> i%2 == 0).map(i -> Math.sqrt(i)).collect(Collectors.toList());        elapsed = System.nanoTime() - t0;               System.out.printf("Streams: Elapsed time:\t\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));        //Parallel stream approach        stream = sourceList.stream().parallel();                t0 = System.nanoTime();        result = stream.filter(i -> i%2 == 0).map(i -> Math.sqrt(i)).collect(Collectors.toList());        elapsed = System.nanoTime() - t0;               System.out.printf("Parallel streams: Elapsed time:\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));          }.以下是雙核機(jī)器的結(jié)果:    Collections: Elapsed time:        94338247 ns   (0,094338 seconds)    Streams: Elapsed time:           201112924 ns   (0,201113 seconds)    Parallel streams: Elapsed time:  357243629 ns   (0,357244 seconds)對于這個特定的測試,流的速度大約是集合的兩倍,并行性沒有幫助(或者我使用錯誤的方式?)。問題:這個測試公平嗎?我犯了什么錯嗎?流比收集慢嗎?有誰在這方面做了一個很好的正式基準(zhǔn)?我應(yīng)該采取哪種方法?
查看完整描述

3 回答

?
猛跑小豬

TA貢獻(xiàn)1858條經(jīng)驗(yàn) 獲得超8個贊

LinkedList使用迭代器停止使用除列表中間的大量刪除之外的任何內(nèi)容。


停止手動編寫基準(zhǔn)測試代碼,使用JMH。


適當(dāng)?shù)幕鶞?zhǔn):


@OutputTimeUnit(TimeUnit.NANOSECONDS)

@BenchmarkMode(Mode.AverageTime)

@OperationsPerInvocation(StreamVsVanilla.N)

public class StreamVsVanilla {

    public static final int N = 10000;


    static List<Integer> sourceList = new ArrayList<>();

    static {

        for (int i = 0; i < N; i++) {

            sourceList.add(i);

        }

    }


    @Benchmark

    public List<Double> vanilla() {

        List<Double> result = new ArrayList<>(sourceList.size() / 2 + 1);

        for (Integer i : sourceList) {

            if (i % 2 == 0){

                result.add(Math.sqrt(i));

            }

        }

        return result;

    }


    @Benchmark

    public List<Double> stream() {

        return sourceList.stream()

                .filter(i -> i % 2 == 0)

                .map(Math::sqrt)

                .collect(Collectors.toCollection(

                    () -> new ArrayList<>(sourceList.size() / 2 + 1)));

    }

}

結(jié)果:


Benchmark                   Mode   Samples         Mean   Mean error    Units

StreamVsVanilla.stream      avgt        10       17.588        0.230    ns/op

StreamVsVanilla.vanilla     avgt        10       10.796        0.063    ns/op

正如我預(yù)期的那樣,流實(shí)現(xiàn)速度相當(dāng)慢。JIT能夠內(nèi)聯(lián)所有l(wèi)ambda內(nèi)容,但不會像vanilla版本那樣生成完美簡潔的代碼。


通常,Java 8流不是魔術(shù)。他們無法加速已經(jīng)很好實(shí)現(xiàn)的東西(可能是普通的迭代或Java 5的 - 每個語句都替換為Iterable.forEach()和Collection.removeIf()調(diào)用)。流更多的是編碼方便性和安全性。方便 - 速度權(quán)衡在這里工作。


查看完整回答
反對 回復(fù) 2019-08-30
?
SMILET

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個贊

1)您使用基準(zhǔn)測試時間不到1秒。這意味著副作用會對您的結(jié)果產(chǎn)生強(qiáng)烈影響。所以,我增加了你的任務(wù)10次


    int max = 10_000_000;

并運(yùn)行你的基準(zhǔn)。我的結(jié)果:


Collections: Elapsed time:   8592999350 ns  (8.592999 seconds)

Streams: Elapsed time:       2068208058 ns  (2.068208 seconds)

Parallel streams: Elapsed time:  7186967071 ns  (7.186967 seconds)

沒有edit(int max = 1_000_000)結(jié)果


Collections: Elapsed time:   113373057 ns   (0.113373 seconds)

Streams: Elapsed time:       135570440 ns   (0.135570 seconds)

Parallel streams: Elapsed time:  104091980 ns   (0.104092 seconds)

這就像你的結(jié)果:流比收集慢。結(jié)論:流初始化/值傳輸花費(fèi)了大量時間。


2)增加任務(wù)流后變得更快(沒關(guān)系),但并行流仍然太慢。怎么了?注意:你有collect(Collectors.toList())命令。收集單個集合實(shí)質(zhì)上會在并發(fā)執(zhí)行時引入性能瓶頸和開銷。可以通過替換來估計開銷的相對成本


collecting to collection -> counting the element count

對于流,它可以通過collect(Collectors.counting())。我得到了結(jié)果:


Collections: Elapsed time:   41856183 ns    (0.041856 seconds)

Streams: Elapsed time:       546590322 ns   (0.546590 seconds)

Parallel streams: Elapsed time:  1540051478 ns  (1.540051 seconds)

那是一項(xiàng)艱巨的任務(wù)?。╥nt max = 10000000)結(jié)論:收集物品需要花費(fèi)大部分時間。最慢的部分是添加到列表中。BTW,簡單ArrayList用于Collectors.toList()。


查看完整回答
反對 回復(fù) 2019-08-30
?
繁星coding

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超4個贊

public static void main(String[] args) {

    //Calculating square root of even numbers from 1 to N       

    int min = 1;

    int max = 10000000;


    List<Integer> sourceList = new ArrayList<>();

    for (int i = min; i < max; i++) {

        sourceList.add(i);

    }


    List<Double> result = new LinkedList<>();



    //Collections approach

    long t0 = System.nanoTime();

    long elapsed = 0;

    for (Integer i : sourceList) {

        if(i % 2 == 0){

            result.add( doSomeCalculate(i));

        }

    }

    elapsed = System.nanoTime() - t0;       

    System.out.printf("Collections: Elapsed time:\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));



    //Stream approach

    Stream<Integer> stream = sourceList.stream();       

    t0 = System.nanoTime();

    result = stream.filter(i -> i%2 == 0).map(i -> doSomeCalculate(i))

            .collect(Collectors.toList());

    elapsed = System.nanoTime() - t0;       

    System.out.printf("Streams: Elapsed time:\t\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));



    //Parallel stream approach

    stream = sourceList.stream().parallel();        

    t0 = System.nanoTime();

    result = stream.filter(i -> i%2 == 0).map(i ->  doSomeCalculate(i))

            .collect(Collectors.toList());

    elapsed = System.nanoTime() - t0;       

    System.out.printf("Parallel streams: Elapsed time:\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));      

}


static double doSomeCalculate(int input) {

    for(int i=0; i<100000; i++){

        Math.sqrt(i+input);

    }

    return Math.sqrt(input);

}

我稍微更改了代碼,在我的mac book pro上運(yùn)行了8個內(nèi)核,得到了一個合理的結(jié)果:


收藏:經(jīng)歷時間:1522036826 ns(1.522037秒)


流:經(jīng)過的時間:4315833719 ns(4.315834秒)


并行流:經(jīng)過時間:261152901 ns(0.261153秒)


查看完整回答
反對 回復(fù) 2019-08-30
  • 3 回答
  • 0 關(guān)注
  • 873 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號