もう散々何処かでやってるかと思いますが、今更ながらに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)