2022 Java timing new posture StopWatch

1, Background

  sometimes we need to record the execution time of each task or the execution time of a piece of code during development. The simplest way is to print the difference between the current time and the execution completion time. Generally, we detect the execution time of a piece of code in the following way:

public static void main(String[] args) {
  Long startTime = System.currentTimeMillis();
  // Your business code
  Long endTime = System.currentTimeMillis();
  Long elapsedTime = (endTime - startTime) / 1000;
  System.out.println("Total time for this section:" + elapsedTime + "s");
}
Copy code
 Copy code

   in fact, this method obtains the execution time of the program by obtaining the difference between the execution completion time and the execution start time. It is simple, direct and effective, but it must be annoying to write too much. Especially when encountering indescribable code, people can't help writing more bug chat. Moreover, if you want to further control the execution time, It needs to be modified in many places in the program. At this time, I wonder if there is a tool class that provides these methods to meet this scenario? We can use the stopwatch in the existing tool class. The common stopwatch tool class is org springframework. util. StopWatch,org.apache.commons.lang.time.StopWatch and the stopwatch in guava provided by Google (I haven't used this much). Here we will focus on the use of spring and Apache

2, spring usage

2.1 first encounter

  StopWatch is located at org springframework. A tool class under util package, which can easily time part of the program code (ms level), which is suitable for synchronizing single threaded code blocks. To sum up, the StopWatch timer provided by Spring supports the statistical output of the time characteristics of programs with seconds and milliseconds as units, especially single thread and sequential execution programs. In other words, if we have several tasks that are executed before and after in sequence, and we are more concerned about the time occupation of the execution of several tasks respectively, we hope to form a less complex log output. StopWatch provides such a function. Moreover, Spring's StopWatch is basically implemented only for such functions.
To use it, first you need to introduce the Spring core package into your Maven. Of course, Spring MVC and Spring Boot have automatically introduced the package:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
Copy code
 Copy code

   the cognition of all things starts from use. Let's take a look at its usage, as shown below:

public static void main(String[] args) throws InterruptedException {
    StopWatch stopWatch = new StopWatch();

    // The first mock exam is dormant for 3 seconds.
    stopWatch.start("TaskOneName");
    Thread.sleep(1000 * 3);
    System.out.println("Current task name:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // The first mock exam is dormant for 10 seconds.
    stopWatch.start("TaskTwoName");
    Thread.sleep(1000 * 10);
    System.out.println("Current task name:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // The first mock exam is dormant for 10 seconds.
    stopWatch.start("TaskThreeName");
    Thread.sleep(1000 * 10);
    System.out.println("Current task name:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // Printing out takes time
    System.out.println(stopWatch.prettyPrint());
    System.out.println(stopWatch.shortSummary());
    // After stop, its value is null
    System.out.println(stopWatch.currentTaskName()); 
    
    // Information about the last task
    System.out.println(stopWatch.getLastTaskName());
    System.out.println(stopWatch.getLastTaskInfo());
    
    // The total time-consuming of the task can be used if you want to get the details of each task (including its task name, time-consuming, etc.)
    System.out.println("Total time for all tasks:" + sw.getTotalTimeMillis());
    System.out.println("Total tasks:" + sw.getTaskCount());
    System.out.println("Details of all tasks:" + sw.getTaskInfo());
}
Copy code
 Copy code

   as shown in the figure, StopWatch not only correctly records the execution time of the last task, but also can give the accurate task execution time (nanosecond level) and time-consuming ratio at the end, which may be more elegant than our own output.

2.2 source code

Old rules, from shallow to deep. After reading the usage, let's take a look at the source code. First look at the properties that make up StopWatch

public class StopWatch {
    /**
	 * The unique Id of this instance, which is used to distinguish between log and console output.
	 */
    private final String id;
    /**
	 * Do you want to keep a taskList
	 * Each time the timing is stopped, the current task will be put into this linked list to record the task link and timing analysis
	 */
	private boolean keepTaskList = true;
   /**
	 * Task linked list
	 * It is used to store the information of each task. taskInfo consists of taskName and totoalTime
	 */
    private final List<StopWatch.TaskInfo> taskList;
    /**
	 * Start time of the current task
	 */
    private long startTimeMillis;
    /**
	 * 
	 */
    private boolean running;
    /**
	 * Current task name
	 */
    private String currentTaskName;
    /**
	 * Information for the last task
	 */
    private StopWatch.TaskInfo lastTaskInfo;
    /**
	 * Total tasks
	 */
    private int taskCount;
    /**
	 * Program execution time
	 */
    private long totalTimeMillis;
    ...
}
Copy code
 Copy code

Next, let's take a look at the constructor of the StopWatch class and some key methods

methodexplain
new StopWatch()Build a new stopwatch without starting any tasks.
new StopWatch(String id)Create a StopWatch with the specified id
String getId()Returns the ID of this stopwatch
void start(String taskName)Start the timing of an unnamed task without passing in parameters. Pass in a String type parameter to start the task timing of the specified task name
void stop()Stops the timing of the current task
boolean isRunning()Is a task being timed
String currentTaskName()The name of the currently running task, if any
long getTotalTimeMillis()Total execution time of all tasks (in milliseconds)
double getTotalTimeSeconds()Total time (in seconds) for all tasks
String getLastTaskName()The name of the previous task
long getLastTaskTimeMillis()Elapsed time of the previous task (in milliseconds)
int getTaskCount()Number of scheduled tasks
String shortSummary()A short description of the total run time
String prettyPrint()Gracefully print the detailed time consumption of all tasks

2.3 precautions

  • StopWatch objects are not designed to be thread safe and do not use synchronization.
  • A StopWatch instance can only start one task at a time, and cannot start multiple tasks at the same time
  • You cannot start a new task before the task has stopped. You must stop the task before you can start a new task
  • To open multiple StopWatch instances at a time, you need new different StopWatch instances

3, apache usage

  stopwatch is a task execution time monitor under apache commons lang3 package. It is similar to the behavior of our commonly used stopwatch. Let's take a look at some important methods first:

methodexplain
new StopWatch()Build a new stopwatch without starting any tasks.
static StopWatch createStarted()
void start()Start timing
void stop()Stops the timing of the current task
void reset()Reset timing
void split()Set split point
void unsplit()
void suspend()Pause timing until resume() is called
void resume()Resume timing
long getTime()Count the timing from start to now
long getTime(final TimeUnit timeUnit)
long getNanoTime()
long getSplitTime()Gets the time from start to the last split
long getSplitNanoTime()
long getStartTime()
boolean isStarted()
boolean isSuspended()
boolean isStopped()
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.6</version>
</dependency>
Copy code
 Copy code

   the task execution monitor provided by Apache has rich functions and strong flexibility. The following classic practical cases:

public static void main(String[] args) throws InterruptedException {
    //start immediately after creation, commonly used
    StopWatch watch = StopWatch.createStarted();

    // StopWatch watch = new StopWatch();
    // watch.start();

    Thread.sleep(1000);
    System.out.println(watch.getTime());
    System.out.println("Statistics of running time from start to present:" + watch.getTime() + "ms");

    Thread.sleep(1000);
    watch.split();
    System.out.println("from start Time to date:" + watch.getTime());
    System.out.println("Run time from start to first pointcut:" + watch.getSplitTime());


    Thread.sleep(1000);
    watch.split();
    System.out.println("Run time from start to second pointcut:" + watch.getSplitTime());

    // After reset, re time
    watch.reset();
    watch.start();
    Thread.sleep(1000);
    System.out.println("The current running time after restart is:" + watch.getTime());

    // Pause and resume
    watch.suspend();
    System.out.println("Pause for 2 seconds");
    Thread.sleep(2000);

    // suspend above. If you want to re count here, you need to restore it
    watch.resume();
    System.out.println("The execution time after recovery is:" + watch.getTime());

    Thread.sleep(1000);
    watch.stop();

    System.out.println("Time spent" + watch.getTime() + "ms");
    // Direct conversion to s
    System.out.println("Time spent" + watch.getTime(TimeUnit.SECONDS) + "s");
}
Copy code
 Copy code

4, Finally

  many times, writing code is also an art, and with the help of this practical tool, I feel more artistic. I hope we can have the heart to pursue better things, which is particularly important for accepting new knowledge. This monitor is recommended here to replace the previous use, so that partners can analyze your code more flexibly~

Keywords: Java Spring Back-end Programmer

Added by Alelinux on Wed, 05 Jan 2022 12:11:19 +0200