测量异步方法的执行时间

时间:2018-05-31 18:59:02

标签: java spring junit spring-async deferred-result

我有异步方法,我使用DeferredResult作为返回类型。我想为该方法编写junit测试,我在循环中调用此方法,例如100次,并且我需要为该方法的每次调用测量执行时间。

以下是方法示例:

@Transactional(readOnly = true)
@Override
public DeferredResult foo() {
    DeferredResult dr = new DeferredResult(5000L, "timeout");
    dr.onCompletion(() -> {
        // do some stuff
    });
    deferredResults.add(dr);

    return dr;        
}

创建deferredResult我添加到集合中,我在另一个方法中迭代该集合,我设置了一些结果,然后是dr返回。

你能告诉我看起来应该如何测试我能测量该方法多次调用的执行时间吗?

@Test
public void executionTimeTest() {
    for (int i = 0; i < 100; i++) {
        asyncService.foo();
    }

    // here I need get execution time for each call
}

感谢。

1 个答案:

答案 0 :(得分:0)

我认为解决此问题的最佳方法是在spring docs推荐的DeferredResult类中添加其他数据。准确地说,春季文档中的以下句子指出了这种可能性。

  

子类可以扩展此类以轻松关联其他数据   或DeferredResult的行为。例如,人们可能想要   通过扩展来关联用于创建DeferredResult的用户   类并为用户添加其他属性。就这样,   用户可以在以后轻松访问,而无需使用数据   结构来做映射。

鉴于这种可能性,您可以扩展DeferredResult并添加开始和结束时间:

public class MyDeferredResult extends DeferredResult {

    long startTime;
    long endTime;

    public MyDeferredResult(Long timeout, Object timeoutResult) {
        super(timeout, timeoutResult);
        this.startTime = System.currentTimeMillis();
    }

    @Override
    public boolean setResult(Object result) {
        boolean r = super.setResult(result);
        this.endTime = System.currentTimeMillis();
        return r;
    }

    public long totalTime() {
        return (endTime - startTime)/1000;
    }

}

然后,您的异步服务可能与此类似:

 public MyDeferredResult foo() {
    MyDeferredResult dr = new MyDeferredResult(5000L, "timeout");
    new Thread(() -> {
        Random r = new Random();
        System.out.println("async task started");
        try {
            Thread.sleep(r.nextInt(4) * 1000 );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("async task finished");
        dr.setResult("test async result");
    }).start();
    deferredResults.add(dr);
    return dr;
}

boolean hasResults() {
    boolean result = true;
    for(MyDeferredResult dr: deferredResults) {
        result = result && dr.hasResult();
    }
    return result;
}

最后,在测试中,您可以检索每次执行的总时间:

   @Test
    public void executionTimeTest() {
        Service service = new Service();
        for (int i = 0; i < 10; i++) {
            service.foo();
        }

       while (!service.hasResults()) {
            System.out.println("No result yet");
       }

        for(MyDeferredResult dr: service.deferredResults) {
            System.out.println(dr.totalTime());
        }
    }