首页 > 解决方案 > 用于对 Java 类进行基准测试的 JMH 与 JMeter?

问题描述

如果我想在我的 Java 类中对方法进行基准测试,哪一个是更好的选择?两者之间的优缺点是什么?

标签: javajmeterload-testingmicrobenchmarkjmh

解决方案


我对 JMeter 和 JMH 都有很多经验。我想说有很多情况你可以使用它们中的任何一个,但是在Java 类基准测试的范围内,只有 JMH 是真正相关的,你不能用 JMeter 进行类级别的基准测试,它只是一个粗略的近似。或者,如果您的班级正在执行一些长时间的操作,而精度并不那么重要,它可能会起作用。原因:

  • JMeter 自身的开销很大。例如,我有一个测试函数 X 的 JMH 测试,它的平均时间约为 0.01 毫秒。我还在 JMeter 中使用此函数在自定义 Java 采样器中进行设置。该采样器通常显示大约 20 毫秒的平均值。这是 200 倍的差异,就像 JMeter 开销一样。

  • 使用 JMeter,您无法避免 JVM 优化,这使得基准测试实际上变得不切实际(尽管由于问题 #1,它可能根本不重要)。JMH 有一种机制来防止这种陷阱。我认为在 JMeter 中你不能以任何干净的方式解决这个问题。

我也不同意 Dmitri T 的概念,即它具有“有限数量的模式”——它实际上具有比 JMeter 更多的相关模式,并且它们更容易设置:

  • 首先,它有多种模式可供您选择(包括“保持负载的时间”)。它还具有一次使用所有模式的能力(具有单独的结果),因此您不必选择单一模式,您可以单独通过注释或命令行参数指定它。在 JMeter 中,只有通过额外的开发(例如单独的线程组或测试)才有可能。
  • JMH 没有加速,但它有预热,允许从结果中排除初始执行,从而确保结果从初始启动噪声中清除,这与加速的目标基本相同
  • 肯定有控制迭代的方法:数量、时间等;通过注释或命令行。

在 JMH 中还有很多非常容易的事情,在 JMeter 中它们需要很多不同的解决方法。例如:

  • 同步迭代是 JMH 中的注释问题,但需要在 JMeter 中进行仔细设置。
  • 不对称测试,允许您同时测试生产者/消费者模型,但独立测量它们。在 JMH 中,你编写你的测试,用注解标记它们,你就完成了。在 JMeter 中,您需要大量开销才能正确设置它

在报告方面,JMH 很像 JMeter 有用于 Jenkins 和 TeamCity 的插件,可以生成结果表和图表。它还可以发布各种格式的结果,这些结果可以被其他工具使用、处理或存储。

那么,如果 JMH 如此出色,那么JMeter 有什么用呢?

  • 主要用于测试各种网络协议,而 JMH 不是为该用例构建的。这是您可能不关心 JMeter 的开销或 JVM 优化的地方,并且可以利用 JMeter 中的内置采样器。当然,没有什么可以阻止您使用 JMH 测试任何网络协议(只要您使用适当的库)。但是在 JMeter 中,您无需编写自定义代码来处理通信协议。

  • 您不能/不想编写 Java 代码。在 JMeter 中,您可以直观地表达您的逻辑,这使得不编写代码的人可以编写测试(尽管您可能仍然需要使用一些编程概念来控制测试的逻辑,例如循环或计时器,并且您可能在前/后处理中需要一些脚本)。如果可以使用可视化记录(即记录 HTTP 测试),它也很有吸引力。

  • 您可能还会觉得 JMeter 测试处于“功能”测试级别,而 JMH 测试处于“单元”测试级别。但这是相当主观的。


推荐阅读