Eclipse、Maven 和 JMH:没有匹配的基准
Eclipse, Maven & JMH: No matching benchmarks
我有一个相关的 pom.xml
as
的 maven 项目
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>0.1</version>
</dependency>
我按照官方的例子here 。
我的 App.java
class 看起来像这样:
public class App
{
@GenerateMicroBenchmark
public void run()
{
System.out.println("Hello World");
}
public static void main( String[] args ) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + App.class.getSimpleName() + ".*")
.forks(1)
.build();
new Runner(opt).run();
}
}
当我通过 Eclipse 运行 时,我仍然收到以下错误。
No matching benchmarks. Miss-spelled regexp? Use -v for verbose output.
问题是 JMH 默认情况下会查看目录 /META-INF/MicroBenchmarks
以查找 运行 的基准,但 Maven 不会将 类 编译到该目录。要使其在 Eclipse 中工作,请参考 this answer。
但是,我建议您 运行 直接在命令行上进行基准测试(Eclipse 会增加一些开销)。
我注意到您使用的是 0.1 版,这是 JMH 的第一个版本。最好更新到最新版本。开始使用 JMH 的最佳方法是使用原型 jmh-java-benchmark-archetype
:
生成项目
$ mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=jmh-test \
-Dversion=1.0
这将从头开始生成一个Maven 项目,使用最新的JMH 版本,预先配置,您无需担心打包问题。然后,您可以将这个新项目作为现有的 Maven 项目导入 Eclipse,并开始编写基准代码。
之后,您只需运行:
$ cd jmh-test/
$ mvn clean install
$ java -jar target/benchmarks.jar
为了让您快速入门,这里有一个基准测试示例(什么都不做...)。
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
@Warmup(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(3)
@State(Scope.Benchmark)
public class StreamTest {
@Benchmark
public void benchmark() {
// code here
}
}
我有一个相关的 pom.xml
as
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>0.1</version>
</dependency>
我按照官方的例子here 。
我的 App.java
class 看起来像这样:
public class App
{
@GenerateMicroBenchmark
public void run()
{
System.out.println("Hello World");
}
public static void main( String[] args ) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + App.class.getSimpleName() + ".*")
.forks(1)
.build();
new Runner(opt).run();
}
}
当我通过 Eclipse 运行 时,我仍然收到以下错误。
No matching benchmarks. Miss-spelled regexp? Use -v for verbose output.
问题是 JMH 默认情况下会查看目录 /META-INF/MicroBenchmarks
以查找 运行 的基准,但 Maven 不会将 类 编译到该目录。要使其在 Eclipse 中工作,请参考 this answer。
但是,我建议您 运行 直接在命令行上进行基准测试(Eclipse 会增加一些开销)。
我注意到您使用的是 0.1 版,这是 JMH 的第一个版本。最好更新到最新版本。开始使用 JMH 的最佳方法是使用原型 jmh-java-benchmark-archetype
:
$ mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=jmh-test \
-Dversion=1.0
这将从头开始生成一个Maven 项目,使用最新的JMH 版本,预先配置,您无需担心打包问题。然后,您可以将这个新项目作为现有的 Maven 项目导入 Eclipse,并开始编写基准代码。
之后,您只需运行:
$ cd jmh-test/
$ mvn clean install
$ java -jar target/benchmarks.jar
为了让您快速入门,这里有一个基准测试示例(什么都不做...)。
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
@Warmup(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(3)
@State(Scope.Benchmark)
public class StreamTest {
@Benchmark
public void benchmark() {
// code here
}
}