注:パフォーマンスの問題については、ではなく、です。私は説明できない/理解できないパフォーマンスの違いだけを観察します。HashMapのパフォーマンスJava 9 Java 8より25%少ない?
Java 9をターゲットにして新しく開発されたコードをベンチマークしているうちに、私は奇妙なことを発見しました。 HashMap
の5つのキーを持つ(非常に)単純なベンチマークは、Java 9がJava 8よりもはるかに遅いことを示しています。これは説明できますか、私の(ベンチマーク)コードは間違っていますか?
コード:
@Fork(
jvmArgsAppend = {"-Xmx512M", "-disablesystemassertions"}
)
public class JsonBenchmark {
@State(Scope.Thread)
public static class Data {
final static Locale RUSSIAN = new Locale("ru");
final static Locale DUTCH = new Locale("nl");
final Map<Locale, String> hashmap = new HashMap<>();
public Data() {
hashmap.put(Locale.ENGLISH, "Flat flashing adjustable for flat angled roof with swivel");
hashmap.put(Locale.FRENCH, "Solin pour toit plat inclinée");
hashmap.put(Locale.GERMAN, "Flachdachkragen Flach Schrägdach");
hashmap.put(DUTCH, "Plakplaat vlak/hellend dak inclusief glijschaal");
hashmap.put(RUSSIAN, "Проход через плоскую кровлю регулир. для накл. кровли");
}
}
@Benchmark
public int bmHashMap(JsonBenchmark.Data data) {
final Map<Locale, String> m = data.hashmap;
int sum = 0;
sum += m.get(Data.RUSSIAN).length();
sum += m.get(Locale.FRENCH).length();
sum += m.get(Data.DUTCH).length();
sum += m.get(Locale.ENGLISH).length();
sum += m.get(Locale.GERMAN).length();
return sum;
}
}
結果:
- のJava 8_151:JsonBenchmark.bmHashMapは、Java 9_181 40 47948546.439±560763.711のops /秒
- をthrpt:JsonBenchmark.bmHashMapは40の34962904.479±276045.691 OPSをthrpt /秒(-/27%!)
更新
お返事ありがとうございました。
@Holgerによる提案。私の最初の反応は:それは説明でなければなりません。しかし、私がベンチマークである
String#length()
関数だけでは、パフォーマンスに大きな違いはありません。そして、私がHashMap#get()
メソッド(@Eugeneの示唆)をベンチマークした場合でも、まだ約10-12%の違いがあります。@Eugeneによる提案。パラメータを変更しました(ウォームアップの回数が増え、メモリが増えました)が、結果を再現できません。しかし私はヒープを4Gに増やしました。しかし、これは違いを説明することはできませんか?
@Alan Batemanによる提案。はい、これによりパフォーマンスが向上します。しかし、まだ約20%の差です。
と私はあなたがこれを否定する気にしないだろう全部。可能であれば(jmhの初心者ですが)、両方のバージョンで '.length'の複雑さの比較を記述できますか?答えを見て、理解しながら統計的に見ることは素晴らしいことでしょう。私が何かを見つけ出すことができるかどうかを調べるために[ここ](http://cr.openjdk.java.net/~shade/8085796/notes.txt)を見ましたが、そのほとんどが私の頭を越えました。 – nullpointer
いい答えです。コンパクトな文字列を使用しないときのパフォーマンスを見るために、-XX:-CompactStringsを挙げてください。 –
@nullpointer:古い実装は 'array.length'に似ていましたが、新しい実装は' arrays.length >> coder'のようなものです。wheres coderは文字列に応じて0または1です。実際のアプリケーションの影響は、 'length()'が実際に呼び出される頻度と、latin1文字列と他の文字列の比率に依存します。他の文字列演算では、latin1文字列(バイトを減らすバイト数)がさらに高速になる可能性があります。 – Holger