【问题标题】:How to benchmark asynchronous operations with JMH如何使用 JMH 对异步操作进行基准测试
【发布时间】:2017-10-02 14:50:57
【问题描述】:

我正在尝试对具有以下形式的异步操作进行基准测试:

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()怎么样?这是一个 micro 基准测试框架,而不是集成测试框架。
  • 我想做一个 milli 基准测试,而不是集成测试。根据 jmh 页面:“JMH 是一种 Java 工具,用于构建、运行和分析用 Java 和其他针对 JVM 的语言编写的 nano/micro/milli/macro 基准。”例如,如果我想对 AsynchronousFileChannel (docs.oracle.com/javase/7/docs/api/java/nio/channels/…) 进行基准测试怎么办?在 cb.complete() 中没有什么可以进行基准测试的,因为所有工作都发生在调用完成之前。
  • 我明白了。我试图建议同步执行操作,但我不明白你的 API。作为一个更熟悉的例子,如果我有Runnable,在我的应用程序中,我提交给Executor,对于JMH,我会直接调用它的run() 方法。在op() 方法中创建类似Runnable 的东西,并提交给执行程序?

标签: java jmh


【解决方案1】:

你可以这样写:

  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)
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多