このアプローチの 1 つの欠点は、doSomething()
実行にかかる「実際の」時間が、システムで実行されている他のプログラムとその負荷によって大きく異なる可能性があることです。これにより、パフォーマンス測定が多少不正確になります。
コードがシングルスレッドであると仮定して、コードの実行にかかる時間を追跡するもう 1 つの正確な方法は、呼び出し中にスレッドによって消費される CPU 時間を調べることです。これは JMX クラスで行うことができます。特に、とThreadMXBean
。ThreadMXBean
fromのインスタンスを取得できますjava.lang.management.ManagementFactory
。プラットフォームがサポートしている場合 (ほとんどの場合)、 のgetCurrentThreadCpuTime
代わりに メソッドを使用System.currentTimeMillis
して、同様のテストを実行します。ミリ秒ではなくナノ秒で時間をgetCurrentThreadCpuTime
報告することに注意してください。
測定を実行するために使用できるサンプル (Scala) メソッドを次に示します。
def measureCpuTime(f: => Unit): java.time.Duration = {
import java.lang.management.ManagementFactory.getThreadMXBean
if (!getThreadMXBean.isThreadCpuTimeSupported)
throw new UnsupportedOperationException(
"JVM does not support measuring thread CPU-time")
var finalCpuTime: Option[Long] = None
val thread = new Thread {
override def run(): Unit = {
f
finalCpuTime = Some(getThreadMXBean.getThreadCpuTime(
Thread.currentThread.getId))
}
}
thread.start()
while (finalCpuTime.isEmpty && thread.isAlive) {
Thread.sleep(100)
}
java.time.Duration.ofNanos(finalCpuTime.getOrElse {
throw new Exception("Operation never returned, and the thread is dead " +
"(perhaps an unhandled exception occurred)")
})
}
(上記を自由に Java に翻訳してください!)
この戦略は完璧ではありませんが、システム負荷の変動の影響を受けにくくなっています。