読者です 読者をやめる 読者になる 読者になる

S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

Java8で初めてのStream API

技術メモ Java

周りでStream API使った方がいいんじゃない?的な話があったので、自分でも使ったことないのでテストコード書いてみた。

1つの処理(サンプルの中だと計算処理ロジック)が小さいと、parallelStreamで並列処理すると処理時間が掛かってしまうのとか確認できた。

もっとしょぼい処理/件数ならFor文の方が速かったりもする。

なお、普通にFor文で処理する場合とstreamで処理する場合は、CPU使用率(1コアしか使ってない感じ)の傾向も処理時間も直列で処理してる感じで大体同じ。

parallelStreamは、CPU使用率が100%まで上がってて、並列で処理してるのが確認できた。

public class StreamTest {

    // 処理のループ回数
    private static int LOOP = 100000;

    // stream処理する整数値のリスト
    private List<Integer> list = new ArrayList<Integer>();

    public StreamTest() {
        // stream処理する整数値を生成する
        for ( int i = 1 ; i <= LOOP ; i++ ) {
            this.list.add(i);
        }
    }

    // 計算処理インターフェース
    @FunctionalInterface
    public interface CalcSumInterface {
        public Long calc(Integer p);
    }

    // 計算処理ロジック(1から与えられた整数valueの総和を求める)
    private CalcSumInterface calcSumClass = new CalcSumInterface() {
        public Long calc(Integer value) {
            Long ret = 0L;
            //System.out.println("###### Start stream " + value);
            for ( int i = 1 ; i <= value ; i++ ) ret++;
            //System.out.println("###### End stream   " + value);
            return ret;
        }
    };

    public static void main(String[] args) {
        StreamTest test = new StreamTest();
        System.out.println(">>> LOOP : " + LOOP);
        // forで計算処理を実行する
        test.testFor();
        // streamで計算処理を実行する
        test.testStream();
        // parallelStreamで計算処理を実行する
        test.testParallelStream();
    }

    private void testFor() {
        System.out.println(">>> Start for");
        long s = System.nanoTime();
        for (Integer v : this.list) calcSumClass.calc(v);
        long e = System.nanoTime();
        System.out.println(">>> End for : [ms]" + ((e - s)/1000000));
    }

    private void testStream() {
        System.out.println(">>> Start stream");
        long s = System.nanoTime();
        //this.list.stream().forEach(v -> System.out.println(v));
        this.list.stream().forEach(v -> calcSumClass.calc(v));
        long e = System.nanoTime();
        System.out.println(">>> End stream : [ms]" + ((e - s)/1000000));
    }

    private void testParallelStream() {
        System.out.println(">>> Start parallelStream");
        long s = System.nanoTime();
        //this.list.parallelStream().forEach(v -> System.out.println(v));
        this.list.parallelStream().forEach(v -> calcSumClass.calc(v));
        long e = System.nanoTime();
        System.out.println(">>> End parallelStream : [ms]" + ((e - s)/1000000));
    }

}
  • ループ回数が少ないと、streamの方が速い(誤差の範囲?)。というかFor文の方がもっと速いw
>>> LOOP : 1000
>>> Start for
>>> End for : [ms]16
>>> Start stream
>>> End stream : [ms]57
>>> Start parallelStream
>>> End parallelStream : [ms]74
  • ループ回数を多くすると、parallelStreamの方が速い。
>>> LOOP : 10000
>>> Start for
>>> End for : [ms]419
>>> Start stream
>>> End stream : [ms]416
>>> Start parallelStream
>>> End parallelStream : [ms]310