いくつかの高スループット データ構造のメモリ ベンチマークに取り組んでいるときにImmutableMap
、少しリファクタリングするだけで を使用できることに気付きました。
これは改善になると考えて、これをミックスに投入したところ、 よりも遅いだけでなく、シングルスレッド環境では!HashMap
よりも一貫して遅いように見えることに驚きました。ConcurrentHashMap
完全なベンチマークを見ることができます
テストの本質は非常に単純で、マップに存在する可能性のある多数のランダムな文字列を取得するのにかかる時間です。
public static void timeAccess(Map<String,String> map) {
Random rnd = new Random(seed);
int foundCount = 0;
long start = System.nanoTime();
for(int i = 0; i < loop; i++) {
String s = map.get(RndString.build(rnd));
if(s != null)
foundCount++;
}
long stop = System.nanoTime() - start;
System.out.println("Found "+foundCount+" strings out of "+loop+" attempts - "+
String.format("%.2f",100.0*foundCount/loop)+" success rate.");
System.out.println(map.getClass().getSimpleName()+" took "+
String.format("%.4f", stop/1_000_000_000.0)+" seconds.");
System.out.println();
}
そして、すべて同じ値を含む a HashMap
、 a ConcurrentHashMap
、および anに対してこれを実行するとImmutableMap
、使用時に劇的な速度低下が一貫して示され、ImmutableMap
多くの場合 15% 以上遅くなりました。マップがまばらであるほど (つまり、map.get()
null が返される頻度が高いほど)、格差は大きくなります。サンプル実行の結果は次のとおりです。
Found 35312152 strings out of 100000000 attempts - 35.31 success rate.
HashMap took 29.4538 seconds.
Found 35312152 strings out of 100000000 attempts - 35.31 success rate.
ConcurrentHashMap took 32.1465 seconds.
Found 35312152 strings out of 100000000 attempts - 35.31 success rate.
RegularImmutableMap took 37.9709 seconds.
これは文書化された/予想される問題ですか? Guava DocsImmutable***
はメモリ効率が高いことを示していますが、速度については何も述べていません。この程度の速度低下の場合、私はメモリ コストに対処し、Immutable***
速度が問題になる場合 (そうでない場合は?!) を回避する傾向があります。何か不足していますか?
参照: https://groups.google.com/forum/?fromgroups=#!topic/guava-discuss/I7yPpa5Hlpg