如何使用JMH对异步操作进行基准测试

3

我正在尝试对形如下面的异步操作进行基准测试:

void op(Callback cb);

我可以使用以下方法进行基准测试:

@Benchmark
void issueOp(BenchState state) {
    state.svc.op(nullCb);
}

但这只测量了发出操作的时间,而不是完成时间。

@Benchmark
void issueOp(BenchState state) {
   final CountDownLatch latch = new CountDownLatch(1);
   Callback signalCb = new Callback() {
       public void complete() {
           latch.countDown();
       }
   };
   state.svc.op(signalCb);
   signalCb.await();
}

它确实测量完成时间,但一次只排队一个操作。

我真的很想要这样的东西:

@AsyncBenchmark
void issueOp(BenchState state, final BenchmarkCompletion bc) {
    Callback cb = new Callback() {
        void complete() {
            bc.complete();
        }
    };
    state.svc.op(cb);
}

BenchmarkCompletion是JMH提供的一种指示操作完成的功能。

JMH中是否有类似的功能?


评测一下 cb.complete() 怎么样?这是一个微型基准测试框架,而不是集成测试框架。 - erickson
我想进行一次毫秒级基准测试,而不是集成测试。 根据JMH页面:“JMH是一个Java工具,用于构建、运行和分析使用Java和其他针对JVM的语言编写的纳米/微型/毫秒/宏观基准测试。”例如,如果我想对AsynchronousFileChannel(https://docs.oracle.com/javase/7/docs/api/java/nio/channels/AsynchronousFileChannel.html#write(java.nio.ByteBuffer,%20long,%20A,%20java.nio.channels.CompletionHandler))进行基准测试怎么办?因为所有的工作都在完成调用之前发生,所以在cb.complete()中没有任何需要基准测试的内容。 - Benjamin Reed
我明白了。我曾试图建议同步执行该操作,但我没有理解你的API。举个更熟悉的例子,如果我有一个Runnable在我的应用程序中提交给一个Executor,那么在JMH中,我会直接调用它的run()方法。在op()方法内部创建一个类似于Runnable的东西,然后将其提交给执行器吗? - erickson
1个回答

2
你可以像这样编写内容:
  final private val OperationsPerInvocation = 10000
  @Benchmark
  @OperationsPerInvocation(OperationsPerInvocation)
  def schedulePeriodicallyBenchmark(): Unit = {
    val latch = new CountDownLatch(OperationsPerInvocation)
    timeServiceScheduler.schedulePeriodically(Duration.ofMillis(100)) {
      latch.countDown()
    }
    latch.await(20, TimeUnit.MINUTES)
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接