我在JMeter和JMH方面有很多经验。我认为有很多情况下可以使用其中任何一个,但在Java类基准测试的范围内,只有JMH真正相关。你不能使用JMeter进行类级别的基准测试,它只会是粗略的近似值,或者如果你的类执行一些长时间操作,那么可能会起作用,但精度并不重要。原因:
JMeter本身的开销非常大。例如,我有一个JMH测试来测试函数X,平均值大约为0.01ms。我还在JMeter中使用该函数来在自定义Java采样器中设置某些内容。该采样器通常显示约20ms的平均值。这是200倍的差异,即JMeter的开销。
使用JMeter无法避免JVM优化,使得基准测试实际上不切实际(尽管由于问题#1,这可能并不重要)。JMH有一种机制可以防止这种问题。我不认为在JMeter中可以以任何干净的方式解决这个问题。
我不同意Dmitri T的观点,认为它有“有限的模式”-
实际上,它具有比JMeter更多相关的模式,并且更容易设置:
- 首先,它有几种可供选择的模式(包括“负载保持时间”)。它还可以同时使用所有模式(具有单独的结果),因此您不必选择单个模式,并且只需通过注释或命令行参数指定即可。在JMeter中,只有通过额外开发才可能实现(例如,分离线程组或测试)。
- JMH没有ramp-up,但是它有warmup,可以从结果中排除初始执行,从而确保结果不受初始启动噪声的影响,这实质上与ramp-up的目标相同。
- 肯定有控制迭代次数的方法:数量、时间等,可以通过注释或命令行控制。
此外,在JMH中有很多东西非常容易,而在JMeter中则需要很多各种各样的解决方法。例如:
- 在JMH中,同步迭代只需要注释,但在JMeter中需要仔细设置。
-
asymetric测试允许您同时测试生产者/消费者模型,但独立地测量它们。在JMH中,您编写测试,用注释标记即可完成。在JMeter中,您需要大量开销来正确设置它。
就报告而言,JMH与JMeter一样,具有适用于Jenkins和TeamCity的插件,可以生成结果表格和图形。它还可以以各种格式发布结果,这些结果可以被其他工具消耗、处理或存储。
那么,如果JMH如此出色,那么JMeter适合做什么?
主要用于测试各种网络协议,而JMH不是为此用例构建的。在这种情况下,您可能不关心JMeter的开销或JVM优化,并且可以利用JMeter中的内置采样器。当然,您也可以使用JMH测试任何网络协议(只要使用适当的库)。但是,在JMeter中,您无需编写自定义代码来处理通信协议。
如果您不能/不想编写Java代码,在JMeter中,您可以以可视方式表达逻辑,这使得不会编程的人编写测试成为可能(尽管您仍然可能需要使用一些编程概念来控制测试的逻辑,例如循环或计时器,并且您可能需要一些脚本来进行前/后处理)。如果您可以使用它(即如果您记录HTTP测试),则可视录制也可能很有吸引力。
您还可能觉得JMeter测试是“功能性的”,而JMH测试是“单元”测试级别。但那是相当主观的。