Note: This is not about a performance issue. I only observe a difference in performance I cannot explain / understand.
在对一些针对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;
}
}
结果:
更新
感谢您的回答和好评。
String#length()
函数进行基准测试,则性能不会有显着差异。而且,当我仅对HashMap#get()
方法(由@Eugene建议)进行基准测试时,仍然存在大约10-12%的差异。 最佳答案
您正在测试的不仅仅是HashMap
。您不仅在调用HashMap.get
,而且在隐式调用Locale.hashCode
和Locale.equals
。此外,您正在调用String.length
。
现在,这四种方法都可能改变了它们的性能特征,因此您将需要进行更多的测试才能推断出哪种方法表现出不同的性能。
但是 HitTest 门的候选人是String.length
。在Java 9中,String
类不再使用char[]
数组,而是使用byte[]
数组对每个字符仅使用一个字节的拉丁语1字符串进行编码,从而大大减少了典型应用程序的内存占用量。但是,这意味着该长度不再总是与数组长度相同。因此,此操作的复杂性已更改。
但请记住,您的结果在一个微基准测试中相差约77 ns。这还不足以估计对实际应用程序的影响…
关于performance-testing - Java 9的HashMap性能是否比Java 8低25%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46988645/