如何在gradle中使用JMH?

igr*_*igr 17 gradle jmh

我想使用带有gradle的OpenJDK 微基准测试工具JMH.但是,我在编译时获得了NPE.另一方面,JMH在使用maven时工作.

我不发布任何内容,build.gradle因为它是基本的 - 应用java插件并添加对JHM工具的依赖(org.openjdk.jmh:jmh-core:0.2).

我试过这里写的没有成功.

还有什么我需要做的?我认为设置代理的东西,但我仍然没有想出来.

例外:

:compileJava
java.lang.NullPointerException
at org.openjdk.jmh.processor.internal.GenerateMicroBenchmarkProcessor.validMethodSignature(GenerateMicroBenchmarkProcessor.java:502)
Run Code Online (Sandbox Code Playgroud)

Jak*_*ski 19

目前你可以使用专用的插件jmh-gradle-plugin

它需要最少的配置,允许您运行JMH基准测试以及构建基准测试工件

  • 不可能运行单独的测试,不可能为每个测试使用单独的 jvm_args,等等。如果您只是想“玩”JMH - 当然,如果您打算认真对待它 - 这是一个很大的NOGO。 (2认同)
  • 看起来该插件现在可以配置为运行单独的测试,使用单独的 JVM 参数等。请参阅[配置选项](https://github.com/melix/jmh-gradle-plugin#configuration-options)。 (2认同)

igr*_*igr 9

我的坏,我试图对一个有参数的方法进行基准测试 - 当然JMH不会知道要传递什么:)一旦我创建了一个没有参数的void方法,一切都有效.

我的build.gradle:

defaultTasks 'build'

apply plugin: 'java'
apply plugin: 'shadow'

buildscript {
    repositories {
        mavenCentral()
        maven {
            name 'Shadow'
            url 'http://dl.bintray.com/content/johnrengelman/gradle-plugins'
        }
    }
    dependencies {
        classpath 'org.gradle.plugins:shadow:0.7.4'
    }
}

jar {
    manifest {
        attributes 'Main-Class': 'org.openjdk.jmh.Main'
    }
}

repositories {
    mavenCentral()
}


build.doLast {
    tasks.shadow.execute()
}

shadow {
    outputFile = new File('build/libs/microbenchmarks.jar')
}

ext {
    lib = [
        ... other dependencies...
        jmh:            'org.openjdk.jmh:jmh-core:0.2'
    ]
}

dependencies {
    compile lib... other dependencies...
    compile lib.jmh
}

sourceCompatibility = 1.7
Run Code Online (Sandbox Code Playgroud)

构建测试和jar:

gw clean build
Run Code Online (Sandbox Code Playgroud)

然后运行它们:

java -jar build/libs/microbenchmarks.jar ".*" -wi 2 -i 10 -f 2 -t 16
Run Code Online (Sandbox Code Playgroud)

UPDATE

从最新版本的JMH开始,您还需要将依赖项添加到:

org.openjdk.jmh:jmh-generator-annprocess:0.5.4
Run Code Online (Sandbox Code Playgroud)

你可以使用shadow 0.8.

  • 是的,但JMH应该打印出更明智的错误信息.您是否可以尝试将之前的错误基准提供给1.0-SNAPSHOT版本的jmh(需要从源代码构建)?我在那里重建了验证代码的重要部分. (2认同)

bob*_*bah 8

刚完成我的“ 杰作 ”。没有uber-jars,没有插件,代码库与main&test分开,基准编译挂接到main,但是在主流生命周期中不会自动运行。简单,明确且易于破解的香草gradle。

我直接从IntelliJ运行它,要在一个盒子上运行,您可能需要uber-jar back :-)

在进行此操作之前,我花了很多时间尝试使该插件正常工作,但是就我的口味而言,它太笨拙了。

下面是分步细分。

定义一个sourceSet名为jmhclasspath 的新方法,该方法与主方法挂钩sourceSet

sourceSets {
    jmh {
        java.srcDirs = ['src/jmh/java']
        scala.srcDirs = ['src/jmh/scala']
        resources.srcDirs = ['src/jmh/resources']
        compileClasspath += sourceSets.main.runtimeClasspath
    }
}
Run Code Online (Sandbox Code Playgroud)

为其定义依赖项(至少JMH及其注释处理器)。

dependencies {
    ...
    jmhImplementation 'org.openjdk.jmh:jmh-core:1.21'
    jmhImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.21'
}
Run Code Online (Sandbox Code Playgroud)

定义任务jmh类型JavaExec

task jmh(type: JavaExec, dependsOn: jmhClasses) {
    main = 'org.openjdk.jmh.Main'
    classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath
}
Run Code Online (Sandbox Code Playgroud)

钩子jmhClasses任务运行,classes以确保基准测试与其余代码一起编译

classes.finalizedBy(jmhClasses)
Run Code Online (Sandbox Code Playgroud)


bar*_*uin 6

我制作了一个非常小的示例项目,可以根据需要进行克隆和修改。这是一个完整的工作示例:
https ://gitlab.com/barfuin/jmh-gradle-example

它不需要影子 Jars 和插件,同时仍然在专用 JVM 中运行基准测试。该项目还包括一些额外的 Gradle 任务,用于打印类路径、JMH 选项等,这些内容可能有助于理解正在发生的事情。