search
LoginSignup
0

More than 5 years have passed since last update.

螺旋祭り Advent Calendar 2016 Day 12

posted at

Java8のStreamを試す

もう散々何処かでやってるかと思いますが、今更ながらにJava8でStream使ったときのパフォーマンスを試してみます。

環境

■Java

java
$ java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

■Eclisep

Version: Neon.1a Release (4.6.1)

テストメソッド

引数

  • StringのList

やること

  • リストをソート
  • リストをループさせて、StringBuilderで連結
  • リストの文字列が特定の文字で始まる場合は除外

Streamを使わないコード

    public void sortList(List<String> list) {
        StringBuilder sb = new StringBuilder();
        Collections.sort(list);
        for (String str : list) {
            if (!str.startsWith("ぺ")) {
                sb.append(str);
            }
        }
    }

Streamを使ったコード

    public void sortList(List<String> list) {
        StringBuilder sb = new StringBuilder();
        list.stream()
                .filter(str -> !str.startsWith("ぺ"))
                .sorted()
                .forEach(str -> sb.append(str));
    }

メソッドを実行するコード

テストメソッドを100万回ループする処理を10回実行します。

    public static void main(String[] args) {
        // テストメソッドの引数で使用するリスト
        List<String> list = Arrays.asList(
                "ゆうてい"
                ,"みやおう"
                ,"きむこう"
                ,"1234567"
                ,"abcdefg"
                ,"ぺぺぺぺ"
                );

        // テスト実行のループもStreamで書いてみる
        IntStream.rangeClosed(1, 10).forEach(i -> {
            long start = System.currentTimeMillis();
            StreamTest test = new StreamTest();
            IntStream.rangeClosed(1, 1000000).forEach(j -> {
                test.sortList(list);
            });
            System.out.println("[time]" + (System.currentTimeMillis() - start) + "(msec)");
        });
    }

結果

Streamを使わないコード

[time]174(msec)
[time]144(msec)
[time]161(msec)
[time]117(msec)
[time]136(msec)
[time]204(msec)
[time]132(msec)
[time]133(msec)
[time]126(msec)
[time]127(msec)

Streamを使ったコード

[time]526(msec)
[time]442(msec)
[time]684(msec)
[time]373(msec)
[time]378(msec)
[time]335(msec)
[time]363(msec)
[time]364(msec)
[time]390(msec)
[time]353(msec)

結論

今回試したコードでは、Streamを使った場合、倍〜倍以上の時間がかかってました。
が、単純な処理での大量ループなので、この結果になったと思われます。(実用する場合は一概に同様の結果にはならないような気がしてます。)
また、初めてのStreamの実装なので、Streamを活かした実装ができてないかもしれません。
可読性については、今回のテストの場合、今までのコードで慣れている人は明らかにfor文を使ったほうが見やすいとは思いますが、
なれるとStreamを使った構文も一目瞭然で、わかりやすいのかなと感じました。

ちなみに、以下のコードにするとちょっと早くなりました。

    public void sortListAsStream(List<String> list) {
        StringBuilder sb = new StringBuilder();
        list.stream()
                .sorted()
                .forEach(str -> {
                    if (!str.startsWith("ぺ")) {
                        sb.append(str);
                    }
                });
    }
[time]456(msec)
[time]409(msec)
[time]328(msec)
[time]552(msec)
[time]316(msec)
[time]257(msec)
[time]272(msec)
[time]289(msec)
[time]305(msec)
[time]306(msec)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0