Java 8のStream APIのparallelStreamを計測する

| コメントをどうぞ

前記事 Java 8のラムダ式とStream APIを使ってみる ではstreamを使ってみました。今度はparallelStreamを使って、パフォーマンスを計測してみます。

SalesDataクラスを用意し、データを生成させる。

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class SalesData {
    private Date date;        // 売上日
    private int salesAmount;  // 売上金額
    private String location;    // 地域

    public SalesData(Date date, int salesAmount, String location){
        this.date = date;
        this.salesAmount = salesAmount;
        this.location = location;
    }

    public int getSalesAmount() {
        return salesAmount;
    }

    public String getLocation() {
        return location;
    }

    private static final int[] SALES_AMOUNTS = {
        1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000
    };
    private static final String[] LOCATIONS = {
        "東京", "千葉", "埼玉", "神奈川", "茨城", "栃木", "群馬"
    };
    public static List<SalesData> createSalesDateList() {
        List<SalesData> salesDataList = new ArrayList();
        // 2014/1/1のDateを生成
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(2014, 1, 1);

        // 1,000,000日分のデータを作成する
        for (int i = 0; i < 1000000; i++) {
            Date salesDate = calendar.getTime();
            // 売上金額ごとのデータを作成する
            for (int salesAmount : SALES_AMOUNTS) {
                // 地域ごとのデータを作成する
                for (String location : LOCATIONS) {
                    salesDataList.add(new SalesData(salesDate, salesAmount, location));
                }
            }
            calendar.add(Calendar.DAY_OF_MONTH, 1); // 日付を1日加算
        }
        return salesDataList;
    }
}

従来のloop、stream、parallelStreamの比較のため、5回実行する。

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<SalesData> salesDataList = SalesData.createSalesDateList();
        for (int i=0; i<5; i++) loop(salesDataList);
        for (int i=0; i<5; i++) stream(salesDataList);
        for (int i=0; i<5; i++) parallelStream(salesDataList);
    }
    static void loop(List<SalesData> salesDataList) {
        long start = System.currentTimeMillis();
        int maxSalesAmount = -1;
        for (SalesData salesData : salesDataList) {
            // 地域が「東京」のもので絞る
            if (salesData.getLocation().equals("東京")) {
                // 最大の売り上げを取得する
                if (maxSalesAmount < 0) {
                    maxSalesAmount = salesData.getSalesAmount();
                } else if (maxSalesAmount < salesData.getSalesAmount()) {
                    maxSalesAmount = salesData.getSalesAmount();
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("loop: time=" + (end - start) + "ms");
    }
    static void stream(List<SalesData> salesDataList) {
        long start = System.currentTimeMillis();
        int maxSalesAmount = salesDataList.stream()
                .filter(salesData -> salesData.getLocation().equals("東京"))
                .mapToInt(salesData -> salesData.getSalesAmount())
                .max()
                .getAsInt();
        long end = System.currentTimeMillis();
        System.out.println("stream: time=" + (end - start) + "ms");
    }
    static void parallelStream(List<SalesData> salesDataList) {
        long start = System.currentTimeMillis();
        int maxSalesAmount = salesDataList.parallelStream()
                .filter(salesData -> salesData.getLocation().equals("東京"))
                .mapToInt(salesData -> salesData.getSalesAmount())
                .max()
                .getAsInt();
        long end = System.currentTimeMillis();
        System.out.println("parallelStream: time=" + (end - start) + "ms");
    }
}

実行結果はこちら

loop: time=315ms
loop: time=290ms
loop: time=284ms
loop: time=274ms
loop: time=273ms
stream: time=340ms
stream: time=296ms
stream: time=338ms
stream: time=330ms
stream: time=333ms
parallelStream: time=236ms
parallelStream: time=118ms
parallelStream: time=118ms
parallelStream: time=112ms
parallelStream: time=111ms

loopとstreamはほとんど変わらないかstreamの方が少し遅い。
parallelStreamの1回目はほとんど変わらないが、2回目以降に高速化していることが分かる。

【参考】
ラムダ式で本領を発揮する関数型インターフェースとStream APIの基礎知識 (3/3)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>