Edited at

業務で役に立ったJava No.3 for,streamのメモリ使用量

More than 1 year has passed since last update.

forを回すのがめんどくさいのでリストの作成を基本全部streamで書いていたら

先輩に「streamは実質for文だからメモリの無駄遣いです。」

と言うレビューをもらい少しムカついたので調べてみました。

簡単なメモリ測定メソッドを使ってみて


まずは何もしない状態

DecimalFormat f1 = new DecimalFormat("#,###KB");

DecimalFormat f2 = new DecimalFormat("##.#");
long free = Runtime.getRuntime().freeMemory() / 1024;
long total = Runtime.getRuntime().totalMemory() / 1024;
long max = Runtime.getRuntime().maxMemory() / 1024;
long used = total - free;
double ratio = (used * 100 / (double)total);
String info =
"Java メモリ情報 : 合計=" + f1.format(total) + "、" +
"使用量=" + f1.format(used) + " (" + f2.format(ratio) + "%)、" +
"使用可能最大="+f1.format(max);
System.out.println(info);

Java メモリ情報 : 合計=125,952KB、使用量=1,997KB (1.6%)、使用可能最大=1,864,192KB


次に10000までの数値をfor分を使って3つに分類

List<Integer> list = new ArrayList<>();

List<Integer> devided1 = new ArrayList<>();
List<Integer> devided2 = new ArrayList<>();
List<Integer> devided3 = new ArrayList<>();
for(int i = 1; i<=10000 ; i++) {
list.add(i);
}
for(Integer num : list) {
if(num % 3 == 1) {
devided1.add(num);
}
if(num % 3 == 2) {
devided2.add(num);
}
if(num % 3 == 0) {
devided3.add(num);
}
}

Java メモリ情報 : 合計=125,952KB、使用量=2,665KB (2.1%)、使用可能最大=1,864,192KB


最後にstreamを使って同じこと

List<Integer> devided1 = list.stream()

.filter(i -> i%3 ==1)
.collect(Collectors.toList());
List<Integer> devided2 = list.stream()
.filter(i -> i%3 ==2)
.collect(Collectors.toList());
List<Integer> devided3 = list.stream()
.filter(i -> i%3 ==0)
.collect(Collectors.toList());

Java メモリ情報 : 合計=125,952KB、使用量=3,995KB (3.2%)、使用可能最大=1,864,192KB

先輩生意気言ってごめんなさい。

やっぱり同じ様な処理を3回回すとそれだけメモリを食うんですね。

この数値を見る限り同じ処理一度だとしてもforの方が使用量は少なそうです。

「実質for文」という言い方には疑問があるけど

やはり何でもかんでも新しいものを使えばいいわけではない。

ただ可読性、書きやすさはやはり後者かなと思います。