集合在耗時程序中流遍歷、迭代遍歷的效率測量對比

測試環境

    操做系統:WIN10
    邏輯處理器:4核
    運行內存:16G

測試程序:

CloudLogVo.java

import lombok.Data;

/**
 * @className: CloudLogVo
 * @description: 日誌信息Vo
 * @author: niaonao
 **/
@Data
public class CloudLogVo {

    private String level;
    private String location;
    private String message;
    private String time;

    public CloudLogVo(String level, String location, String message, String time) {
        this.level = level;
        this.location = location;
        this.message = message;
        this.time = time;
    }
}

TraversalTimeConsume.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @className: TraversalStatisticsConsumeTime
 * @description: 耗時操做的測試類
 * 此處使用 System.out.print() 模擬耗時操做;爲何耗時?點進去看內部實現,write()方法就很重量級
 * @author: niaonao
 **/
public class TraversalTimeConsume {

    // 遍歷測試集合
    private static List<CloudLogVo> voList = null;

    /**
     * @description: 內部類:for-i 線程類
     */
    class ForIThread extends Thread {
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            for (int i = 0; i < voList.size(); i++) {
                voList.get(i).getLevel();
                System.out.print("");
            }
            long end = System.currentTimeMillis();
            System.out.println("         for-i: " + (end - start));
        }
    }

    /**
     * @description: 內部類:foreach 線程類
     */
    class ForeachThread extends Thread {
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            for (CloudLogVo item : voList) {
                item.getLevel();
                System.out.print("");
            }
            long end = System.currentTimeMillis();
            System.out.println("       foreach: " + (end - start));
        }
    }

    /**
     * @description: 內部類:stream 線程類
     */
    class StreamThread extends Thread {
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            voList.stream().forEach(item -> {
                item.getLevel();
                System.out.print("");
            });
            long end = System.currentTimeMillis();
            System.out.println("        stream: " + (end - start));
        }
    }

    /**
     * @description: 內部類:parallelStream 線程類
     */
    class ParallelStreamThread extends Thread {
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            voList.parallelStream().forEach(item -> {
                item.getLevel();
                System.out.print("");
            });
            long end = System.currentTimeMillis();
            System.out.println("parallelStream: " + (end - start));
        }
    }

    /**
     * @description: 初始化集合
     */
    private static void initList(int quantity) {
        List<CloudLogVo> cloudLogVoList = new ArrayList<>(quantity);
        for (int i = 0; i < quantity; i++) {
            String value = String.valueOf(i);
            cloudLogVoList.add(new CloudLogVo(value, value, value, value));
        }
        voList = Collections.synchronizedList(cloudLogVoList);
    }

    public static void main(String[] args) throws InterruptedException {
        // 遍歷量級
        int quantity = 1 * 1000 * 1000;
        initList(quantity);
        // 統計遍歷耗時
        TraversalTimeConsume.ForIThread forIThread = new TraversalTimeConsume().new ForIThread();
        TraversalTimeConsume.ForeachThread foreachThread = new TraversalTimeConsume().new ForeachThread();
        TraversalTimeConsume.StreamThread streamThread = new TraversalTimeConsume().new StreamThread();
        TraversalTimeConsume.ParallelStreamThread parallelStreamThread = new TraversalTimeConsume().new ParallelStreamThread();

        new Thread().sleep(2000);
        forIThread.start();
        foreachThread.start();
        streamThread.start();
        parallelStreamThread.start();
    }
}

測試量級

    測試數據量級以下java

data: ['10萬','30萬','40萬','50萬','60萬','70萬','100萬','150萬','200萬','300萬']

測試結果

    縱座標爲耗時/毫秒,橫座標爲集合量級。數據量級越大,統計耗時數據偏差越小。編程


遍歷結構體存在耗時程序時,綜合來看:ide

  • 加強for循環表現較好,foreach效率總體較高
  • 在 65 萬級數據量左右,parallelStream 效率會超過 foreach,隨着數據量級增長,差距增大
  • stream 與 parallelStream 在 50 萬數量級別以後,parallelStream 遍歷效率更高,而且隨着數據量增大,差距越大。另外 parallelStream 相對 stream 來講支持並行處理。
  • 普通 for 循環和 stream 全程陪跑,不要細看,不忍直視X...X。

附:非耗時程序集合遍歷效率圖

    附圖:非耗時遍歷程序測試數據圖
    非耗時操做,stream 內部作了些不可描述的事情,相對普通 for 循環必定要多耗時的。普通 for 循環和加強 for 循環始終優於 stream,而 foreach 是更優的選擇。
    Stream API 藉助 Lambda 表達式提升編程效率及程序可讀性,提供了串行、並行來進行匯聚操做。優點在於可讀性,簡潔性和並行效率。測試

    以上數據存在偏差,僅作參考。this

Power By niaonao, The End
相關文章
相關標籤/搜索