问题标签 [jmh]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
802 浏览

java - JMH 中分叉之间的不同基准测试结果

简而言之,我的问题是:为什么 JMH 基准测试结果可以在 fork 中保持稳定,但在 fork 之间却存在显着差异。

我在许多基准测试中都观察到了这一点(通常涉及数据集的处理)。这是一个简单的例子:

我使用 5 次一秒预热迭代和 15 次一秒测量迭代。整个过程重复 50 次(连同 JVM 重新启动),如@Fork(50). 通常的分叉看起来像这样:

如您所见,每次迭代的结果非常稳定,标准偏差很低。但是有时(可能几十次)我会看到这样的分叉:

结果也相当稳定,但比通常的分叉慢 2 倍以上。

这是每个分叉的摘要(按平均时间排序的分叉数、平均时间和以微秒为单位的标准偏差):

如您所见,对于大多数迭代,平均值落入5.142..5.174 us区间,然后小跳到5.210..5.249 us区间,然后大跳到5.625..5.858 us,然后是两个异常值。原始结果可在此gist中获得。

那么这些跳跃和异常值是什么?是基准测试程序故障还是这样的效果也会出现在生产中,并且我的程序在极少数情况下会变慢 2.5 倍?这是一些与硬件或 JVM 相关的问题吗?我可以在执行开始时预测我是在快速分叉还是慢速分叉?

使用 Oracle JDK 1.8.0_45 和 JMH 1.10.3 在 Windows 7 64 位 Intel i5 QuadCore 系统中执行测量。

0 投票
1 回答
904 浏览

java - JMH 和 Mode.AverageTime 的 OutOfMemory

我正在编写一个微基准来比较使用+运算符与StringBuilder的字符串连接。为此,我创建了一个基于OpenJDK 示例的 JMH 基准测试类,该示例使用了batchSize参数

当我运行基准测试时,我收到以下stringBuilderConcatenation方法错误:

我在想必须增加默认的 JVM 堆大小,所以我尝试使用JMH 提供的选项允许最多 10GB 的-Xmx10G值。-jvmArgs不幸的是,我仍然得到错误。

因此,我尝试将batchSize参数的值减小到1,但仍然得到OutOfMemoryError

我发现的唯一解决方法是将基准模式设置为Mode.SingleShotTime. 由于这种模式似乎将批处理视为单次拍摄(即使s/op显示在 Units 列中),似乎我得到了我想要的指标:执行一组批处理操作的平均时间。但是,我仍然不明白为什么它不能与Mode.AverageTime.

另请注意,stringConcatenation无论使用何种基准模式,方法的基准都会按预期工作。该问题仅发生在stringBuilderConcatenation使用 StringBuilder 的方法上。

欢迎任何帮助理解为什么前面的示例无法使用设置为的基准模式Mode.AverageTime

我使用的 JMH 版本是1.10.4

0 投票
3 回答
891 浏览

java - 这个 JMH 基准在机器之间不一致——为什么?

我正在尝试编写这样的方法:

我正在努力寻找最有效的实施方式。我选择了一个,但后来一位同事运行了基准测试并得到了不同的相对结果。对我来说最快的实现对他来说并不是最快的。

这些基准有什么问题吗?

我们的环境存在细微差别。

我:Windows 10,JDK 1.8.0_45,“zeros”是最快的

他:Windows 7,JDK 1.8.0_20,“cast”最快

无论是在 IDE 中运行还是从命令行运行,我们的结果在每次运行中都是自洽的。我们正在使用 JMH 1.10.5。

这里发生了什么?基准似乎不可信,我不知道如何解决它。

0 投票
1 回答
180 浏览

java - JMH,Microbenchmark部分代码

我想看看是否有办法告诉 JMH 只测量一个特定的方法,即从微基准调用的所有方法。

我想以单元测试为基础自动创建微基准,因此我不必手动构建微基准。在我的研究中,我有一个庞大的代码库,我做了一些自动修改,期望它们会对性能产生影响。到目前为止,我在代码中有 1200 个位置被修改。自动化是必要的,因为我们希望提供一个框架来进行转换,然后自动测量转换的影响。

这里JMH:不要考虑提供解​​决方案的内部方法时间,但是我必须手动分离@Start方法中的代码,这似乎与1200个测试用例无关......

0 投票
0 回答
75 浏览

java - 第一次热身比平均速度快得多

我有一个非常简单的微基准

当我运行它时,我总是得到第一次热身运行比下一次运行快得多的结果:

命令行:

使用分叉或线程的数量似乎没有什么区别。

所以看起来一些优化被恢复了,但我找不到它是什么。

性能下降是由于我的基准测试问题还是这种去优化代表了实际应用程序中会发生的情况?

注意:这是在 mapToInt 之后调用 map 的后续操作,在需要的地方调用 map 有什么好处吗?

0 投票
1 回答
2986 浏览

java - JMH 中的操作数到底是多少?

@OperationsPerInvocationJava Microbenchmarking Harness (JMH)中的注释 JavaDoc指出:

value 公共抽象 int 值

Returns:每个 Benchmark 调用的操作数。默认值:1

作为 JMH 的新手,我想知道这里指的是什么类型的操作(字节码操作、汇编代码操作、Java 操作等)。

这个问题自然是指 JMH 中所有使用“操作”一词的地方(文档、输出、评论等)(例如“操作/时间”单位或“时间单位/操作”)。

0 投票
1 回答
1458 浏览

java - 使用 JMH 测试 Spring MVC 吞吐量

所以我试图在没有容器的情况下对 Spring MVC(主要只是使用 REST 控制器)进行一些基准测试;只是 Spring 及其请求处理。有了泽西岛,我可以做这样的事情:

ApplicationHandler是 Jersey 请求处理的主要入口点。我所有的 Jersey 配置都在JerseyConfig. 基本上所有发生的事情是我创建请求(ContainerRequest),然后处理请求只是对处理程序进行调用,传递请求。请求经过请求处理周期后,返回响应。

我试图用 Spring MVC 模仿同样的功能。真的,我什至不知道我将如何去做。我刚开始往墙上扔东西,希望它能粘住。我有点想也许我可以用DispatcherServlet(或更准确地说FrameworkSevlet)来做到这一点。但为了做到这一点,我能看到的唯一方法是processRequest通过反射使受保护的对象可以访问。这是我的尝试

这虽然行不​​通。我在这条线上得到了一个 NPE ,我猜这意味着它webApplicationContext是空的。但我在上面设置它。

NPE 与否,我什至不确定我是否以正确的方式进行此操作;如果我应该研究其他一些组件而不是DispatcherServlet.

任何人有任何想法如何使这项工作?我应该研究另一个组件,调用不同的方法吗?我可能缺少任何配置来实际使我的上述尝试起作用?

要求立场

  • 使用 JMH
  • 仅测试 Spring 处理请求到响应的吞吐量。

在 GitHub 上查看完整的可运行项目

0 投票
1 回答
676 浏览

java - System.arraycopy 具有恒定长度

我正在玩 JMH ( http://openjdk.java.net/projects/code-tools/jmh/ ),我只是偶然发现了一个奇怪的结果。

#clone()我正在对制作数组的浅拷贝的方法进行基准测试,我可以观察到预期的结果(循环遍历数组是一个坏主意,System#arraycopy()并且在性能方面没有显着差异Arrays#copyOf())。

除了System#arraycopy()当数组的长度被硬编码时会慢四分之一......等等,什么?这怎么能慢?

有谁知道可能是什么原因?

结果(吞吐量):

和基准类:

0 投票
1 回答
550 浏览

java - JMH。公开微基准测试的结果

我读过,为了避免在微基准测试中消除死代码,最常见的解决方案是:

  1. 返回计算结果
  2. 使用黑洞消耗结果。

我的问题是:

是否可以通过将计算结果放在公共变量中来避免死代码消除?

编辑:

感谢 Shipilev 的回答,我意识到返回结果或使用黑洞使用它们必须正确完成,以避免死代码消除 (DCE),如 JMH 示例中所述。

因此,我将重写我的问题以使其更清楚:

在返回计算结果或与 blackholes 一起使用足以避免 DCE 的情况下,是否也足以将结果放入公共变量中?

我已经运行了示例JMHSample_08_DeadCode的变体,如下所示:

从结果看来是这样:

0 投票
1 回答
1055 浏览

java - Java 无锁性能 JMH

我有一个 JMH 多线程测试:

  1. 在当前变体中,我的性能 ~ 55 ops/us
  2. 但是,如果我取消注释“Special line”,或者用 unsafe.putOrderedObject 替换它(在任何方向 - current.next = oo.next = current),性能 ~ 2 ops/us。

据我了解,这是 CPU 缓存发生的事情,也许它正在清理存储缓冲区。如果我确实将它替换为基于锁的方法,没有 CAS,性能将是 11-20 ops/us。
我尝试使用 LinuxPerfAsmProfiler 和 PrintAssembly,在第二种情况下我看到:

有人可以向我解释到底发生了什么吗?为什么这么慢?这里的存储负载障碍在哪里?为什么 putOrdered 不起作用?以及如何解决?