在不创建单独的 maven 项目的情况下使用 jmh 对代码进行基准测试
Using jmh to benchmark code without creating separate maven project
我正在开发一个 Maven 项目,我希望使用 jmh 来对我的代码进行基准测试。我想组织我的项目,使其包含源代码、单元测试和基准测试。 gradle 中似乎有一种方法可以在不创建单独的 gradle 项目的情况下对代码进行基准测试(请参阅 link)。有没有办法在 Maven 中做到这一点?
简短的回答是是。
我在我的项目中遇到过这种目录布局(但你绝对可以更改它)
+- src/
+- main/java - sources
+- test/
+- java - test sources
+- perf - benchmarks
您需要几个插件才能实现。
build-helper-maven-plugin
附加自定义测试源位置
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/perf</source>
</sources>
</configuration>
</execution>
maven-compiler-plugin
to run jmh-generator-annprocess
注释处理器在 test-compile
阶段
<execution>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</execution>
maven-assembly-plugin
创建 运行nable jar with benchmarks
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<attach>true</attach>
<archive>
<manifest>
<mainClass>org.openjdk.jmh.Main</mainClass>
</manifest>
</archive>
</configuration>
</execution>
<assembly>
<id>perf-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
之后你会得到一个带有基准的可执行 jar,它可能像往常一样 运行
java -jar target/your-project-version-perf-tests.jar
你可以看到工作示例here。
注意
此解决方案的唯一缺点是所有测试 类 和测试依赖项也将包含在带有基准测试的 jar 中,这肯定会使它膨胀。但是您可以通过在单独的目录(${project.build.directory}/test-classes
除外)中编译基准来避免它。
我正在开发一个 Maven 项目,我希望使用 jmh 来对我的代码进行基准测试。我想组织我的项目,使其包含源代码、单元测试和基准测试。 gradle 中似乎有一种方法可以在不创建单独的 gradle 项目的情况下对代码进行基准测试(请参阅 link)。有没有办法在 Maven 中做到这一点?
简短的回答是是。
我在我的项目中遇到过这种目录布局(但你绝对可以更改它)
+- src/
+- main/java - sources
+- test/
+- java - test sources
+- perf - benchmarks
您需要几个插件才能实现。
build-helper-maven-plugin
附加自定义测试源位置
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/perf</source>
</sources>
</configuration>
</execution>
maven-compiler-plugin
to runjmh-generator-annprocess
注释处理器在test-compile
阶段
<execution>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</execution>
maven-assembly-plugin
创建 运行nable jar with benchmarks
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<attach>true</attach>
<archive>
<manifest>
<mainClass>org.openjdk.jmh.Main</mainClass>
</manifest>
</archive>
</configuration>
</execution>
<assembly>
<id>perf-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
之后你会得到一个带有基准的可执行 jar,它可能像往常一样 运行
java -jar target/your-project-version-perf-tests.jar
你可以看到工作示例here。
注意
此解决方案的唯一缺点是所有测试 类 和测试依赖项也将包含在带有基准测试的 jar 中,这肯定会使它膨胀。但是您可以通过在单独的目录(${project.build.directory}/test-classes
除外)中编译基准来避免它。