首页 > 解决方案 > 从 JMH 的分析中排除 @Setup 方法

问题描述

我正在使用 JMH 对 JVM 上的一些代码进行基准测试,并且我编写了一个注释为@Setup需要很长时间才能运行的方法的方法。当然,正如预期的那样,此方法不包括在基准测试中 - 但不幸的是,当我尝试使用 JMH 的内置分析支持时,它包括在内,这会用各种不相关的方法调用污染分析报告在实际的基准测试方法本身。这种行为似乎没有在任何地方记录,但在 JMH 源代码中,有以下注释:

// profilers start way before the workload starts to capture
// the edge behaviors.

在 JMH 中似乎没有任何选项可以禁用此行为。如何将@Setup方法以及源自它们的任何堆栈跟踪排除在探查器结果中?(这些@Setup方法不会直接或间接地从@Benchmark方法中调用。)

标签: javaprofilingjmh

解决方案


一个相对明显的方法是避免使用 JMH,而只使用一个分析器。但是,这需要一些设置。在 Java 中,您可以添加一个public static void main方法,或者在 Scala 2.12 中,您可以添加一个object扩展App程序,以创建一个实用程序应用程序,其中应包含以下代码:

Benchmark b = new Benchmark(); // assuming your benchmark is defined in a class called Benchmark
b.setupMethod();
System.out.println("Attach a profiler and then press Enter to continue");
new Scanner(System.in).nextLine();
b.benchmarkedMethod();

如果您正在使用采样分析器并且您benchmarkedMethod的速度非常快,请将其置于for具有多次迭代的循环中,以便程序运行足够长的时间以使采样分析器能够收集足够的样本以生成有用的报告。但是,如果您使用的是尝试记录所有方法调用的传统分析器,并且您的基准测试方法在功能上是确定性的(它做同样的事情,每次都取模不同的内存地址和类似的低级事情),不要这样做那是因为它完全没有必要进行分析。

然后运行实用程序,按照指示附加分析器,然后按 Enter。


推荐阅读