Подтвердить что ты не робот

Как запустить JMH из внутренних тестов JUnit?

Как запустить тесты JMH в моем существующем проекте с помощью тестов JUnit? Официальная документация рекомендует создать отдельный проект, используя плагин Maven shade и запустить JMH внутри метода main. Это необходимо и почему рекомендуется?

4b9b3361

Ответ 1

Я запускал JMH внутри моего существующего проекта Maven, используя JUnit без видимых побочных эффектов. Я не могу ответить, почему авторы рекомендуют делать что-то по-другому. Я не заметил разницы в результатах. JMH запускает отдельную JVM для запуска тестов для их изоляции. Вот что я делаю:

  • Добавьте зависимости JMH к вашему POM:

    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-core</artifactId>
      <version>1.9.3</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-generator-annprocess</artifactId>
      <version>1.9.3</version>
      <scope>test</scope>
    </dependency>
    

    Обратите внимание, что я поместил их в область test.

    В Eclipse вам может потребоваться настроить обработчик аннотации вручную. NetBeans обрабатывает это автоматически.

  • Создайте свой класс JUnit и JMH. Я решил объединить оба в один класс, но это зависит от вас. Обратите внимание, что OptionsBuilder.include - это то, что на самом деле определяет, какие тесты будут запускаться из вашего теста JUnit!

    public class TestBenchmark {
    
          @Test public void 
        launchBenchmark() throws Exception {
    
                Options opt = new OptionsBuilder()
                        // Specify which benchmarks to run. 
                        // You can be more specific if you'd like to run only one benchmark per test.
                        .include(this.getClass().getName() + ".*")
                        // Set the following options as needed
                        .mode (Mode.AverageTime)
                        .timeUnit(TimeUnit.MICROSECONDS)
                        .warmupTime(TimeValue.seconds(1))
                        .warmupIterations(2)
                        .measurementTime(TimeValue.seconds(1))
                        .measurementIterations(2)
                        .threads(2)
                        .forks(1)
                        .shouldFailOnError(true)
                        .shouldDoGC(true)
                        //.jvmArgs("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining")
                        //.addProfiler(WinPerfAsmProfiler.class)
                        .build();
    
                new Runner(opt).run();
            }
    
        // The JMH samples are the best documentation for how to use it
        // http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
        @State (Scope.Thread)
        public static class BenchmarkState
        {
            List<Integer> list;
    
              @Setup (Level.Trial) public void
            initialize() {
    
                    Random rand = new Random();
    
                    list = new ArrayList<>();
                    for (int i : LoopUtils.range (1000))
                        list.add (rand.nextInt());
                }
        }
    
          @Benchmark public void 
        benchmark1 (BenchmarkState state, Blackhole bh) {
    
                List<Integer> list = state.list;
    
                for (int i = 0; i < 1000; i++)
                    bh.consume (list.get (i));
            }
    }
    
  • Процессор аннотации JMH, похоже, не работает с компиляцией в режиме сохранения в NetBeans. Вам может потребоваться выполнить полный Clean and Build при каждом изменении эталонных тестов. (Любые предложения оценены!)

  • Запустите тест launchBenchmark и посмотрите результаты!

    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running net.almson.util.TestBenchmark
    # JMH 1.9.3 (released 12 days ago)
    # VM invoker: C:\Program Files\Java\jdk1.8.0_45\jre\bin\java.exe
    # VM options: <none>
    # Warmup: 2 iterations, 1 s each
    # Measurement: 2 iterations, 1 s each
    # Timeout: 10 min per iteration
    # Threads: 2 threads, will synchronize iterations
    # Benchmark mode: Average time, time/op
    # Benchmark: net.almson.util.TestBenchmark.benchmark1
    
    # Run progress: 0.00% complete, ETA 00:00:04
    # Fork: 1 of 1
    # Warmup Iteration   1: 2.984 us/op
    # Warmup Iteration   2: 3.007 us/op
    Iteration   1: 2.844 us/op
    Iteration   2: 2.832 us/op
    
    
    Result "benchmark1":
      2.838 us/op
    
    
    # Run complete. Total time: 00:00:05
    
    Benchmark                 Mode  Cnt  Score   Error  Units
    TestBenchmark.benchmark1  avgt    2  2.838          us/op
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.255 sec
    
    Results :
    
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    
  • Runner.run даже возвращает RunResult объекты, на которые вы можете делать утверждения, и т.д.