从 JMH 中的分析中排除 @Setup 方法

Exclude @Setup methods from profiling in JMH

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

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

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

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

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 循环中,以便程序 运行s 足够长的时间使采样分析器能够为有用的报告收集足够的样本。但是,如果您使用的是传统的探查器,它试图记录所有方法调用,并且您的基准测试方法在功能上是确定性的(它每次都做同样的事情,模不同的内存地址和类似的低级事情),不要这样做那,因为它完全没有必要进行分析。

然后 运行 实用程序,在提示时附加分析器,然后按 Enter。