我尝试对java方法调用进行基准测试。这些调用的问题在于它们正在内联和优化。
所以最后我试着寻找避免这些优化的方法。目前我使用:
for(int index = 0; index < 100_000_000; index++)
value = value * 2 % 8;
此计算由JNI和Java的方法替换。基准的输出是:
Druation static jni = 1002ms,instance jni = 1000ms,static java = 136ms,instance java = 140ms,raw = 145ms
Druation static jni = 975ms,instance jni = 974ms,static java = 132ms,instance java = 128ms,raw = 134ms
Druation static jni = 966ms,instance jni = 1084ms,static java = 127ms,instance java = 130ms,raw = 135ms
Druation static jni = 958ms,instance jni = 1083ms,static java = 127ms,instance java = 131ms,raw = 134ms
Druation static jni = 957ms,instance jni = 1085ms,static java = 126ms,instance java = 131ms,raw = 135ms
从Java vs raw(无方法)可以看出内联的影响。我想知道我能做些什么来防止内联?
答案 0 :(得分:0)
现代JVM过于复杂,需要进行各种优化。如果您尝试测量一小段代码,那么在没有非常非常详细的知识 JVM正在做的事情的情况下正确执行它真的很复杂。为了解决HotSpot / OpenJDK常见的陷阱,使用JMH很重要。了解how to write a correct microbenchmark
也很重要为了避免内联JMH使用compiler commands:
-XX:CompileCommand=command,method[,option]
例如:
-XX:CompileCommand=dontinline,java.lang.String::indexOf
注意:编译器可能会忽略编译命令。请检查编译器日志和生成的代码:
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintCompilation
-XX:+LogCompilation
-XX:LogFile=./compiler.log
-XX:+PrintInlining
最可靠的方法是禁用所有-XX:-Inline
最好的方法是在this way中使用JMH。
最长的方法是等到JEP 165: Compiler Control完成。