はじめに
配列やコレクションに含まれる特定の型の要素に対して操作を行うにあたり、Streamと拡張for文のどちらが早いのか、処理速度を検証しました。
事前に用意するコード
要素数1億の配列
Object[] objects = new Object[100_000_000];
for (int i = 0; i < 50_000_000; i++)
objects[i] = new Object();
for (int i = 50_000_000; i < 100_000_000; i++)
objects[i] = "";
要素数1億のArrayList
List<Object> objects = new ArrayList<>();
for (int i = 0; i < 50_000_000; i++)
objects.add(new Object());
for (int i = 0; i < 50_000_000; i++)
objects.add("");
今回は配列とArrayListを使って検証します。
Object型、String型の要素をそれぞれ5千万個ずつ格納しています。
検証
Stream
long start = System.currentTimeMillis();
objects.stream() // Arrays.stream(objects)
.filter(String.class::isInstance)
.map(String.class::cast)
.forEach(String::toUpperCase);
long finish = System.currentTimeMillis();
System.out.println(finish - start + "ms");
種類 | 時間 |
---|---|
配列 | 345ms |
ArrayList | 409ms |
配列の方がやや早いようです。
拡張for文
long start = System.currentTimeMillis();
for (Object obj : objects) {
if (obj instanceof String) {
((String) obj).toUpperCase();
}
}
long finish = System.currentTimeMillis();
System.out.println(finish - start + "ms");
種類 | 時間 |
---|---|
配列 | 122ms |
ArrayList | 212ms |
今回の比較では、Streamよりも拡張for文の方が早いということがわかりました1。
普段百万、千万単位の要素数を扱うコードを組まないのであまり意識せずストリームを使うことが多いのですが、パフォーマンスを重視する上では、ストリームは注意して用いる必要がありそうです。
-
計測方法に不備などございましたら、恐れ入りますが教えて頂けますと幸いです。 ↩