使用jmh来编写代码,而无需创建单独的maven项目

时间:2016-08-10 18:24:54

标签: java maven benchmarking jmh

我正在开发一个Maven项目,我希望用jmh来测试我的代码。我想组织我的项目,使其包含源代码,单元测试和基准测试。似乎有一种方法可以在不创建单独的gradle项目的情况下对代码进行基准测试(请参阅link)。有没有办法在Maven中做到这一点?

1 个答案:

答案 0 :(得分:7)

简短回答

我在项目中遇到了这个目录布局(但你绝对可以改变它)

+- src/
   +- main/java   - sources
   +- test/
      +- java        - test sources
      +- perf        - benchmarks

你需要几个插件来实现这一目标。

  1. build-helper-maven-plugin附加自定义测试来源位置
  2. <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>
    
    1. maven-compiler-plugintest-compile阶段运行jmh-generator-annprocess注释处理器
    2. <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>
      
      1. maven-assembly-plugin创建带有基准的可运行jar
      2. <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)目录中编译基准来避免它。