rmu*_*ler 8 performance-testing jmh java-9
注意:这与性能问题无关.我只观察到无法解释/理解的性能差异.
在对一些针对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;
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
UPDATE
感谢您的回答和好评.
@Holger的建议.我的第一反应是:那一定是解释.但是,如果我只对String#length()功能进行基准测试,则性能没有显着差异.而且,当我只对HashMap#get()方法进行基准测试时(如@Eugene所示),仍然存在大约10-12%的差异.
@Eugene的建议.我改变了参数(更多的热身迭代,更多的内存),但我无法重现你的结果.然而,我将堆增加到了4G.但这无法解释差异,不是吗?
@Alan Bateman的建议.是的,这提高了性能!但是,仍然相差20%左右.
您正在测试的不仅仅是HashMap.你不只是打电话HashMap.get,而是暗中打电话Locale.hashCode和Locale.equals.而且,你在打电话String.length.
现在,所有四个都可以改变它们的性能特征,因此您需要更多的测试来推断哪些方法表现出不同的性能.
但最热门的候选人是String.length.在Java 9中,String该类不再使用char[]数组,而是使用byte[]数组,仅使用每个字符一个字节对Latin 1字符串进行编码,从而大大减少了典型应用程序的内存占用.然而,这意味着长度不再总是与阵列长度相同.因此,此操作的复杂性已发生变化.
但请记住,您的结果是微基准测试的差异大约为77 ns .这还不足以估计对实际应用的影响......
我有一个提示,这是关于jmh设置,更多的是关于HashMap.正如已经指出的那样,你在测量的不仅仅是HashMap::get在这里.但即便如此,我还是怀疑java-9会慢得多,所以我自己测量了(最新的jmh构建源自java-8和9).
我没有更改你的代码 - 只是添加了更多堆(10GB)和更热身的方式,从而减少你看到的"错误" ±
使用java-8:
Benchmark Mode Cnt Score Error Units
SOExample.bmHashMap avgt 25 22.059 ± 0.276 ns/op
Run Code Online (Sandbox Code Playgroud)
使用java-9:
Benchmark Mode Cnt Score Error Units
SOExample.bmHashMap avgt 25 23.954 ± 0.383 ns/op
Run Code Online (Sandbox Code Playgroud)
如你所见,结果几乎没有明显差异(毕竟这些是纳秒).此外,如果你真的想测试只是HashMap::get你的方法可以简单地返回它的调用,如下所示:
@Benchmark
@Fork(5)
public int bmHashMap(SOExample.Data data) {
return data.hashmap.get(data.key); // where key is a random generated possible key
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2453 次 |
| 最近记录: |