标签: jmh

使用 JMH Java 微基准测试浮点打印的随机数据

我正在为我编写的浮点打印代码编写 JMH 微基准测试。我还不太关心确切的性能,但要确保基准代码正确。

\n\n

我想循环一些随机生成的数据,因此我制作了一些静态数据数组并保持循环机制(增量和掩码)尽可能简单。这是正确的方法还是我应该告诉 JMH 更多关于我缺少的一些注释的情况?

\n\n

另外,是否可以为测试制作显示组而不仅仅是字典顺序?我基本上有两组测试(每组随机数据一组。

\n\n

完整来源位于https://github.com/jnordwick/zerog-grisu

\n\n

这是基准代码:

\n\n
package zerog.util.grisu;\n\nimport java.util.Random;\n\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.runner.Runner;\nimport org.openjdk.jmh.runner.RunnerException;\nimport org.openjdk.jmh.runner.options.Options;\nimport org.openjdk.jmh.runner.options.OptionsBuilder;\n\n/* \n * Current JMH bench, similar on small numbers (no fast path code yet)\n * and 40% faster on completely random numbers.\n * \n * Benchmark                         Mode  Cnt         Score         Error  Units\n * JmhBenchmark.test_lowp_doubleto  thrpt   20  11439027.798 \xc2\xb1 2677191.952  ops/s\n * JmhBenchmark.test_lowp_grisubuf  thrpt   20  11540289.271 \xc2\xb1  237842.768  ops/s\n * JmhBenchmark.test_lowp_grisustr  thrpt   20   5038077.637 \xc2\xb1  754272.267  ops/s\n * \n …
Run Code Online (Sandbox Code Playgroud)

java performance-testing microbenchmark floating-point-conversion jmh

2
推荐指数
1
解决办法
3742
查看次数

jmh中@Group和@GroupThreads指的是什么?

我一直在研究 jmh 实现“多线程”基准的方式。根据我的理解,注释@Group("Identifier")@GroupThreads(thread_number)启用同一组内的基准测试并行运行。

@Benchmark
@Group("parallel")
@GroupThreads(1)
public void benchmark_1() {
    while(true) {}
}

@Benchmark
@Group("parallel")
@GroupThreads(1)
public void benchmark_2() {
    while(true) {}
}
Run Code Online (Sandbox Code Playgroud)

使用 CPU 监视器,我发现两个 CPU 已充分使用。我想知道跑步者如何解释这些注释。

java jmh

2
推荐指数
1
解决办法
2796
查看次数

为什么 Java 编译的正则表达式比 String::split 中解释的运行速度慢?

我正在尝试改进以下代码:

\n
    public int applyAsInt(String ipAddress) {\n        var ipAddressInArray = ipAddress.split("\\\\.");\n        ...\n
Run Code Online (Sandbox Code Playgroud)\n

所以我将正则表达式编译成静态常量:

\n
    private static final Pattern PATTERN_DOT = Pattern.compile(".", Pattern.LITERAL);\n\n    public int applyAsInt(String ipAddress) {\n        var ipAddressInArray = PATTERN_DOT.split(ipAddress);\n        ...\n
Run Code Online (Sandbox Code Playgroud)\n

其余代码保持不变。

\n

令我惊讶的是,新代码比以前的代码慢。\n以下是测试结果:

\n
Benchmark                                (ipAddress)  Mode  Cnt    Score    Error  Units\nConverterBenchmark.mkyongConverter           1.2.3.4  avgt   10  166.456 \xc2\xb1  9.087  ns/op\nConverterBenchmark.mkyongConverter       120.1.34.78  avgt   10  168.548 \xc2\xb1  2.996  ns/op\nConverterBenchmark.mkyongConverter   129.205.201.114  avgt   10  180.754 \xc2\xb1  6.891  ns/op\nConverterBenchmark.mkyong2Converter          1.2.3.4  avgt   10  253.318 \xc2\xb1  4.977  ns/op\nConverterBenchmark.mkyong2Converter      120.1.34.78  avgt   10  263.045 \xc2\xb1  8.373  ns/op\nConverterBenchmark.mkyong2Converter …
Run Code Online (Sandbox Code Playgroud)

java regex benchmarking split jmh

2
推荐指数
1
解决办法
118
查看次数

在构造函数中设置Java Collection的大小更好吗?

如果我知道那个点的大小,那么传递CollectionCollection构造函数的大小是否更好?扩展Collection和分配/重新分配的节约效果是否显着?

如果我知道最小尺寸Collection而不是上限,该怎么办?至少在最小尺寸的情况下仍然值得创造吗?

java collections microbenchmark jmh

1
推荐指数
2
解决办法
3605
查看次数

jmh 测试只能在 Hotspot 上运行吗?

如何设置 jmh 参数以便可以在不同的虚拟机上运行测试?

我尝试更改 -jvm //虚拟机的路径。

我收到此错误:

Error parsing command line:
 'X' is not a recognized option
<forked VM failed with exit code 1>
<stdout last='20 lines'>
</stdout>
<stderr last='20 lines'>
Error parsing command line:
'X' is not a recognized option
</stderr>
Run Code Online (Sandbox Code Playgroud)

java jvm jmh

1
推荐指数
1
解决办法
244
查看次数

如果可以关闭JIT,为什么要使用JMH?

我想知道如果我可以关闭JIT,为什么我应该使用JMH进行基准测试?JMH是否不会抑制可以通过禁用JIT来防止的优化?

java jit jmh

1
推荐指数
1
解决办法
382
查看次数

两种相同方法的性能差异

我正在阅读JMH框架的示例,我对来自JMHSample_12_Forking的示例代码有疑问.运行此代码后,我有以下结果(正如作者预测的那样):

testJavaUtilConcurrency.JMHSample_12_Forking.measure_1_c1         avgt    5   3.314 ±  0.200  ns/op
testJavaUtilConcurrency.JMHSample_12_Forking.measure_2_c2         avgt    5  22.403 ±  1.023  ns/op
...
Run Code Online (Sandbox Code Playgroud)

该结果解释如下:

注意C1更快,C2更慢,但C1再慢!这是因为 ...

但我的问题是:为什么C2比C1慢?两个类中的代码和两个方法看起来完全相同,那么,性能差异的来源是什么?

更新:

我试图为Counter添加第三个实现并获得以下结果:

testJavaUtilConcurrency.JMHSample_12_Forking.measure_1_c1         avgt    5   3.328 ± 0.073  ns/op
testJavaUtilConcurrency.JMHSample_12_Forking.measure_2_c2         avgt    5   22.437 ± 0.552  ns/op
testJavaUtilConcurrency.JMHSample_12_Forking.measure_2_c3         avgt    5  44.614 ± 5.080  ns/op
testJavaUtilConcurrency.JMHSample_12_Forking.measure_3_c1_again   avgt    5  43.535 ± 1.154  ns/op
Run Code Online (Sandbox Code Playgroud)

java performance jmh

1
推荐指数
1
解决办法
118
查看次数

什么是 StubRoutines::jbyte_disjoint_arraycopy

我正在测量一些单线程方法调用(用 Scala 编写)并想要分析基准测试。这是它的样子(省略了实现细节)

@State(Scope.Benchmark)
class TheBenchmarks {

    var data: Array[Byte] = _
    @Param(Array("1024", "2048", "4096", "8192"))
    var chunkSize: Int = _

    @Setup
    def setup(): Unit = {
        data = //get the data
    }

    @Benchmark
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    @BenchmarkMode(Array(Mode.AverageTime))
    def takeFirstAvroRecord(bh: Blackhole): Unit = {
      val fr = //do computation with data and chunk size
      bh.consume(fr)
    }

}
Run Code Online (Sandbox Code Playgroud)

好吧,我得到了一些结果并想理解它,但 -prof perfasm我有点不清楚它的输出。首先:

....[Hottest Regions]...............................................................................
 44.20%   40.50%        runtime stub  StubRoutines::jbyte_disjoint_arraycopy (205 bytes) 
  6.78%    1.62%         C2, level 4  cats.data.IndexedStateT$$Lambda$21::apply, version 1242 (967 bytes) 
  4.39%    0.79% …
Run Code Online (Sandbox Code Playgroud)

java jvm jmh

1
推荐指数
1
解决办法
2598
查看次数

JMH 不在 Java 模块内运行(无法找到资源:/META-INF/BenchmarkList)

我采用了一个使用maven-surefire-plugin(自动测试)来触发 JMH 基准测试的项目并将其添加module-info.java到其中。现在,META-INF/BenchmarkList不再生成(实际上,整个目录都丢失了)所以我在启动基准测试时最终出现以下错误:

ERROR: Unable to find the resource: /META-INF/BenchmarkList

我怀疑 Java 模块会阻止注释处理器正常运行,但我不知道如何修复它。有任何想法吗?

java maven jmh java-module

1
推荐指数
1
解决办法
2674
查看次数

JMH 设置和拆除

我创建了一个类。在那个类中,我有几个方法被标记为@Benchmark. 我还有一个运行 JMH 基准测试的主要方法:

System.out.println("NUMBER OF THREADS: "+numOfThreads);
Options opt = new OptionsBuilder()
        .include(JMHtopToBottom.class.getSimpleName())
        .warmupIterations(5)
        .measurementIterations(3)
        .forks(numOfThreads)
        .build();

Collection<RunResult> collection = new Runner(opt).run();
Run Code Online (Sandbox Code Playgroud)

我的兴趣是:

  1. 只运行一个的设置方法-new Runner(opt).run();在所有@Benchmark方法被调用之后和之前(以及它们的迭代)。

  2. 同样,有一个拆卸方法,在所有方法运行之后和我们回到主之前只运行一次。

当我试图@setup@tear_down(与Level支持:Trial/ Iteration/ Invocation)的方法运行几次,不仅是我希望的。JMH 中是否有一种方法可以注释方法,以便它只运行方法 - 在结束之后run()和之前run()

jmh

0
推荐指数
1
解决办法
1512
查看次数

为什么微不足道的、看似无关的代码更改对 Java 代码的性能影响如此之大,而在基准测试中却如此?

我多次注意到,微小的、看似无关的代码更改可以改变一段 Java 代码的性能特征,有时甚至是戏剧性的。

这发生在 JMH 和手动基准测试中。

例如,在这样的类中:

class Class<T> implements Interface {
    private final Type field;

    Class(ClassBuilder builder) {
        field = builder.getField();
    }

    @Override
    void method() { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

我做了这个代码更改:

class Class<T> implements Interface {
    private static Class<?> instance;

    private final Type field;

    Class(Builder builder) {
        instance = this;
        field = builder.getField();
    }

    @Override
    void method() { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

和性能发生了巨大变化。

这只是一个例子。在其他情况下,我注意到了同样的事情。

我无法确定是什么原因造成的。我在网上搜索,但没有找到任何信息。

对我来说,它看起来完全无法控制。也许这与编译后的代码在内存中的布局有关?

我不认为这是由于错误共享(见下文)。


我正在开发一个自旋锁:

class SpinLock {
    @Contended // Add compiler option: --add-exports …
Run Code Online (Sandbox Code Playgroud)

optimization performance jvm microbenchmark jmh

0
推荐指数
1
解决办法
161
查看次数

JMH - 较低级别的基准测试

我正在使用 JMH 对 JUnit 测试进行基准测试。

我的基准:

import org.openjdk.jmh.annotations.*;

public class Benchmarks {
        @Benchmark
        public void bmUnitTest1() {
                UnitTests.UnitTest1();
        }

        @Benchmark
        public void bmUnitTest2() {
                UnitTests.UnitTest2();
        }
}
Run Code Online (Sandbox Code Playgroud)

我的基准跑步者:

import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.TimeValue;

import java.util.concurrent.TimeUnit;

public class BenchmarkRunner {
    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
                .include(Benchmarks.class.getSimpleName())
                .mode(Mode.SingleShotTime)
                .resultFormat(ResultFormatType.CSV)
                .result("target/test-classes/benchmarkcsv/BM " + System.currentTimeMillis() + ".csv")
                .timeUnit(TimeUnit.MILLISECONDS)
                .warmupIterations(3)
                .warmupTime(TimeValue.seconds(1))
                .measurementIterations(3)
                .measurementTime(TimeValue.seconds(1))
                .timeout(TimeValue.seconds(5))
                .forks(1)
                .warmupForks(1)
                .threads(1)
                .build();

        new Runner(opt).run(); …
Run Code Online (Sandbox Code Playgroud)

java performance benchmarking jmh

0
推荐指数
1
解决办法
602
查看次数