【问题标题】:Benchmark Java Method Calls基准 Java 方法调用
【发布时间】:2015-05-01 00:09:43
【问题描述】:

我尝试对 java 方法调用进行基准测试。这些调用的问题在于它们正在被内联和优化。

所以最后我尝试寻找一种方法来避免这些优化。目前我使用:

for(int index = 0; index < 100_000_000; index++)
    value = value * 2 % 8;

这个计算被 JNI 和 Java 的方法所取代。基准的输出是:

Druation 静态 jni = 1002ms,实例 jni = 1000ms,静态 java = 136ms,实例 java = 140ms,原始 = 145ms

Druation 静态 jni = 975ms,实例 jni = 974ms,静态 java = 132ms,实例 java = 128ms,原始 = 134ms

Druation 静态 jni = 966ms,实例 jni = 1084ms,静态 java = 127ms,实例 java = 130ms,原始 = 135ms

Druation 静态 jni = 958ms,实例 jni = 1083ms,静态 java = 127ms,实例 java = 131ms,原始 = 134ms

Druation 静态 jni = 957ms,实例 jni = 1085ms,静态 java = 126ms,实例 java = 131ms,原始 = 135ms

从 Java vs raw(无方法)可以看出内联的影响。我想知道是否可以采取一些措施来防止内联?

【问题讨论】:

  • 使用专用的微基准 API,例如 JMH 或 caliper
  • 为什么这是一个“C”题?
  • 因为我将 C 和 Java 混合在一个类中,这表明我在一定范围内具有控制权。
  • Dasiabling 优化?对于性能基准,永远不应该这样做。一个程序在没有优化的情况下可能比另一个程序慢,但在优化后更快,因为它的结构允许它比其他程序更好地优化。使用适当的基准框架。
  • @Raphael 好吧,我需要在没有内联的情况下进行基准测试。我只想简单衡量一个未优化的 java 调用的真正成本以及它与 JNI 调用的比较。在得知 JMH 可以禁用内联后,我更加好奇这是如何实现的。

标签: java c benchmarking jit


【解决方案1】:

免责声明

现代 JVM 太复杂了,做各种优化。如果您尝试测量一小段代码,那么在没有非常非常详细的知识 JVM 正在做什么的情况下正确执行它真的很复杂。为了解决 HotSpot/OpenJDK 常见的陷阱,使用 JMH 很重要。另外重要的是要知道how to write a correct microbenchmark

回答 A

为了避免内联 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

答案 B

最可靠的方法是完全禁用内联-XX:-Inline

答案 C

最好的办法是在this way中使用JMH。

回答 D

最长的方法是等到JEP 165: Compiler Control完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    相关资源
    最近更新 更多