用Spring StopWatch测量Java代码执行时间
malong 发布于 2021-07-04

介绍

衡量代码执行时间是编写高效应用程序的关键步骤。在一台可能为大量用户服务的机器上,对代码的时间感知可以让您进一步规划,并考虑执行时间。

在多线程系统中,测量单个线程或异步任务的执行时间也很有用。

由于在基于Java-for-Spring的解决方案中没有内置的、方便的方法来度量代码执行,所以我们介绍了StopWatch工具。

在本教程中,我们将了解如何使用Spring的秒表测量Java中的代码执行时间。

StopWatch是一个实用程序类,在util包中重新排序。它有一个非常简单的API,允许我们对指定的任务、任务组和程序的总运行时间计时。

此类通常用于在开发阶段检查代码的性能,而不是生产应用程序的一部分。

注意:值得注意的是秒表不是线程安全的。

它依赖于System.nanoTime(),以南秒为单位跟踪时间,这是人们一直在手动执行代码的时间。

StopWatch属于Spring的核心util包:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
</dependency>

当然,它也存在于spring boot starter web依赖中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

StopWatch的API可以归结为创建一个实例并调用start()和stop()——就像用实际的StopWatch计时代码一样。开始计时时,还可以提供一个字符串,用作关联任务的名称或注释。这有助于在结果中区分它们。

任务只是start()和stop()调用之间的时间段。对于在StopWatch启动时创建的每个任务,其名称和执行时间保存在TaskInfo实例中,并添加到任务列表中。

让我们继续创建一个任务,使用名称并度量一段代码的执行时间:

StopWatch timeMeasure = new StopWatch();

timeMeasure.start("Task 1");
Thread.sleep(1000);
timeMeasure.stop();

System.out.println("Last task time in Millis: " 
             + timeMeasure.getLastTaskMillis());

运行结果

Last task time in Millis: 1009

您可以通过getTotalTimeSeconds()、getTotalTimeMillis()和getTotalTimeNanos()访问所有任务的总和。

您还可以通过getLastTaskInfo()访问秒表的最后一个任务,它返回一个TaskInfo实例。此实例包含有关上一个任务的信息,例如名称以及它花费的时间(以秒、毫秒和纳秒为单位):

运行结果

Task 1
1008

在处理多个任务时,一个非常方便的方法是prettyPrint()方法,它以类似表格的方式打印所有记录,格式简单:

// Naming this StopWatch instance
StopWatch stopWatch = new StopWatch("Measure Code Execution");
    
stopWatch.start("1. Task");
Thread.sleep(2000);
stopWatch.stop();
    
stopWatch.start("2. Task");
Thread.sleep(5000);
stopWatch.stop();
 
stopWatch.start("3. Task");
Thread.sleep(3000);
stopWatch.stop();
  
System.out.println(stopWatch.prettyPrint());

输出

StopWatch 'Measure Code Execution': running time = 10012348500 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
2002729600  020%  1. Task
5006985700  050%  2. Task
3002633200  030%  3. Task

注意:如果我们使用StopWatch来测量大量时间间隔(几十万或数百万的顺序)的代码执行时间,TaskInfo列表将消耗大量的工作内存。您可以通过以下方式关闭:

stopWatch.setKeepTaskList(false);

 

malong
关注 私信
文章
35
关注
0
粉丝
0