Как использовать JMH с помощью gradle?

Я хочу использовать JMH инструмент для микрообъектива OpenJDK с gradle. Тем не менее, я получаю 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)

Ответ 1

Только что закончил мой "шедевр". Нет uber-jar, нет плагинов, кодовая база отделена от main & тест, компиляция тестов привязана к основному, но не запускается автоматически в основном жизненном цикле. Простой, понятный и взломанный, ванильный Gradle.

Я запускаю его прямо из IntelliJ, чтобы запустить на коробке, вам, вероятно, понадобится uber-jar назад :-)

До этого я потратил немало времени, пытаясь заставить работать этот плагин, но он слишком неуклюжий на мой вкус.

Пошаговое описание ниже.

Определите новый sourceSet с именем jmh, путь к классу которого будет привязан к основному sourceSet

sourceSets {
    jmh {
        java.srcDirs = ['src/jmh/java']
        scala.srcDirs = ['src/jmh/scala']
        resources.srcDirs = ['src/jmh/resources']
        compileClasspath += sourceSets.main.runtimeClasspath
    }
}

Определите зависимости для него (как минимум, JMH и его процессор аннотаций).

dependencies {
    ...
    jmhImplementation 'org.openjdk.jmh:jmh-core:1.21'
    jmhImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.21'
}

Определите задачу jmh типа JavaExec

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

Подключите задачу jmhClasses к запуску после classes, чтобы убедиться, что тесты производительности скомпилированы с остальным кодом

classes.finalizedBy(jmhClasses)

Ответ 2

В настоящее время вы можете просто использовать выделенный плагин jmh-gradle-plugin

Он требует минимальной конфигурации и позволяет запускать тесты JMH, а также создавать артефакты тестов.

Ответ 3

Мой плохой, я пытался сравнить метод, который имеет аргумент - конечно 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

Сборка тестов и банку:

gw clean build

а затем выполните следующие действия:

java -jar build/libs/microbenchmarks.jar ".*" -wi 2 -i 10 -f 2 -t 16

UPDATE

Из последних версий JMH вам также необходимо добавить зависимость:

org.openjdk.jmh:jmh-generator-annprocess:0.5.4

и вы можете использовать тень 0.8.

Ответ 4

Если вы являетесь пользователем IntelliJ, возможно, самый простой способ заставить его работать без всех обходных путей - это использовать плагин IDE:

https://github.com/artyushov/idea-jmh-plugin

  • Добавьте зависимости
  • Создайте свой ориентир
  • будь счастлив :)