在编写微基准测试时,运行时间会根据方法是否被编译而产生很大差异。有没有一种方法可以从程序内部判断特定的方法是否已编译?或者,是否有一种方法可以请求编译某个方法,或者知道如何充分预热它,而不需要任何关于JVM传递标志的额外信息?显然,这并不一定完美(例如,可能存在某些条件导致JVM回退到解释代码),但肯定会有所改善。
在编写微基准测试时,运行时间会根据方法是否被编译而产生很大差异。有没有一种方法可以从程序内部判断特定的方法是否已编译?或者,是否有一种方法可以请求编译某个方法,或者知道如何充分预热它,而不需要任何关于JVM传递标志的额外信息?显然,这并不一定完美(例如,可能存在某些条件导致JVM回退到解释代码),但肯定会有所改善。
然后,只需使用该数字来“热身”JVM即可。编译之前的方法调用/分支次数
-XX:-PrintCompilation
与-XX:CompileThreshold
一起使用,以便在编译方法时在控制台上通知您。我相信你可以打开日志记录,以显示方法何时被JIT编译。但是我不知道有没有办法从Java内部告诉它。
请记住,JIT编译不是事件,而是一个过程--随着更多关于其特性的信息变得可用,一个方法可能会被重新编译多次。
最后,请注意,“热身”在一般情况下是不确定的。虽然您通常可以可靠地“热身”单个方法,但由于许多因素,对于甚至是适度大的应用程序来说,这要困难得多。
(尽管我不知道为什么不能将某种JITC状态的读取能力添加到嵌入式调试工具中。)
补充:在对“代码片段”进行基准测试时要注意的一件事是,做所有循环的最外层方法通常是不可JITC的(取决于JITC的实现方式),因为它永远不会返回,因此无法调用JITC版本。因此,应始终将要进行基准测试的代码的“主体”放在单独的方法中,该方法被重复调用,而不是将循环和要进行基准测试的代码放在同一个方法中。