JDK 8 HashMap反復性能比較
概要
Mapはキーによるデータへのアクセスが容易で、Javaを含む多くの言語でよく使われるデータ構造です
JavaではO(1)アクセス可能なMapインプリメンテーションHashMapがよく用いられる.
たまに保存した値を全部巡回する必要がある場合もありますか?
(最初はこのようなことは起こらないほうがいいですが…)
仕事をしているうちに、HashMapの反復が必要になることがありました.
リファレンス
参考記事
上記参考文書を受け取った5つの分封の回答では,keySet for,keySet foreach,entrySet for,entrySet foreach,foreachの全値サイクルに対するbanchmarkテスト結果を示した.
その結果,jdk 8はentrysetのforeach ramda処理が最も速いと主張した.
n/a.環境
使用する環境は次のとおりです.
コード#コード#
テスト用に用意したサンプルコードは次のとおりです.
1万環、10回ごとに平均
10万ループ、平均10回ごと
50万ループ、平均10回ごと
100万ループ、平均10回ごと
500万ループ、平均10回ごと
1000万ループ、平均10回ごと
5000万ループ、平均10回ごと
テストの結論
entrySet().forEachまたはvalues()です.いい感じ
JDK 8に追加されたforeach方式は、従来のforサイクル処理と比較して、より高い性能上の利点を有する.
特に驚くべきことに、身長と価値を一度に持ち歩くので、もっと重くなると思っていたEntrySetは思ったよりもほぼ早く処理していた.
このテストコードには整数を加算する単純な動作しか含まれていないため、時間差は小さくなりますが、より複雑な論理を実行すると仮定すると、ループコードごとにパフォーマンスの差が大きくなります.
Mapはキーによるデータへのアクセスが容易で、Javaを含む多くの言語でよく使われるデータ構造です
JavaではO(1)アクセス可能なMapインプリメンテーションHashMapがよく用いられる.
たまに保存した値を全部巡回する必要がある場合もありますか?
(最初はこのようなことは起こらないほうがいいですが…)
仕事をしているうちに、HashMapの反復が必要になることがありました.
リファレンス
参考記事
上記参考文書を受け取った5つの分封の回答では,keySet for,keySet foreach,entrySet for,entrySet foreach,foreachの全値サイクルに対するbanchmarkテスト結果を示した.
その結果,jdk 8はentrysetのforeach ramda処理が最も速いと主張した.
n/a.環境
使用する環境は次のとおりです.
コード#コード#
テスト用に用意したサンプルコードは次のとおりです.
import java.util.Map;
import java.util.HashMap;
public class MapIterComp {
private static int size = 10000, round = 5;
private static long sum, start, end;
private static void print(String name, long value) {
System.out.print(String.format("%-20s: ", name));
System.out.print(String.format("%5d", (end - start)));
System.out.println(" ms");
}
private static void compare() {
final Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < size; i++) map.put(i, i);
System.out.println("[size]: " + size);
System.out.println("[round]: " + round);
// 1. key set for loop
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
for (Integer key: map.keySet()) sum += map.get(key);
end = System.currentTimeMillis();
sum += (end - start);
}
print("keySet() for", sum/round);
// 2. key set for each
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
map.keySet().forEach(k -> sum += map.get(k));
end = System.currentTimeMillis();
sum += (end - start);
}
print("keySet() forEach", sum/round);
// 3. entry set for loop
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
for (Map.Entry<Integer, Integer> e: map.entrySet()) sum += e.getValue();
end = System.currentTimeMillis();
sum += (end - start);
}
print("entrySet() for", sum/round);
// 4. entry set for each
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
map.entrySet().forEach(e -> sum += e.getValue());
end = System.currentTimeMillis();
sum += (end - start);
}
print("entrySet() forEach", sum/round);
// 5. values for loop
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
for (Integer value: map.values()) sum += value;
end = System.currentTimeMillis();
sum += (end - start);
}
print("values() for", sum/round);
// 6. values for each
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
map.values().forEach(v -> sum += v);
end = System.currentTimeMillis();
sum += (end - start);
}
print("values() for each", sum/round);
// 7. for each
sum = 0;
for (int i = 0; i < round; i++) {
start = System.currentTimeMillis();
map.forEach((k, v) -> sum += v);
end = System.currentTimeMillis();
sum += (end - start);
}
print("for each", sum/round);
}
public static void main(String[] args) {
if (args.length == 2) {
size = Integer.valueOf(args[0]);
round = Integer.valueOf(args[1]);
}
if (args.length == 1) size = Integer.valueOf(args[0]);
compare();
}
}
テスト結果1万環、10回ごとに平均
10万ループ、平均10回ごと
50万ループ、平均10回ごと
100万ループ、平均10回ごと
500万ループ、平均10回ごと
1000万ループ、平均10回ごと
5000万ループ、平均10回ごと
テストの結論
entrySet().forEachまたはvalues()です.いい感じ
JDK 8に追加されたforeach方式は、従来のforサイクル処理と比較して、より高い性能上の利点を有する.
特に驚くべきことに、身長と価値を一度に持ち歩くので、もっと重くなると思っていたEntrySetは思ったよりもほぼ早く処理していた.
このテストコードには整数を加算する単純な動作しか含まれていないため、時間差は小さくなりますが、より複雑な論理を実行すると仮定すると、ループコードごとにパフォーマンスの差が大きくなります.
Reference
この問題について(JDK 8 HashMap反復性能比較), 我々は、より多くの情報をここで見つけました https://velog.io/@aaa6400/Java-HashMap-Iterating-성능-비교テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol