注意:這是關於性能問題的而不是。我只觀察到我無法解釋/理解的表現差異。HashMap性能Java 9比Java 8少25%?
基準測試針對Java 9的一些新開發的代碼,我發現了一些奇怪的東西。使用5個鍵的HashMap
(非常)簡單的基準測試表明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;
}
}
結果:
- 爪哇8_151:JsonBenchmark.bmHashMap thrpt 40 47948546.439±560763.711 OPS/s的
- 爪哇9_181:JsonBenchmark.bmHashMap thrpt 40 34962904.479±276045.691 OPS/s(-/- 27%!)
UPDATE
感謝您的回答和很好的評論。
@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',編碼器可以是零或一個,這取決於字符串。實際應用中的影響取決於實際調用'length()'的頻率以及latin1字符串與其他字符串之間的比率。一些其他的字符串操作可能對latin1字符串來說更快(少量字節來剷除),這可能不僅僅是補償。 – Holger