?
StopWatch – elegant program timer
Program timer
During our development process, in order to better monitor the operation of the system, interface, and business, we generally monitor the running time of the program. Initially, we used System.currentTimeMillis() to obtain the start and end times and then subtracted them. Thereby obtaining the program running time, but this method is very cumbersome and not concise and clear enough.
StopWatch
Introduction
StopWatch is available in Spring, Apache, and hutool toolkits. The implementation principles are similar, but some API calls and uses are different.
Let’s first look at the use of StopWatch:
I believe that students who have read the SpringBoot source code should be familiar with this. StopWatch is used when the SpringBoot program starts:
public ConfigurableApplicationContext run(String... args) { stopWatch = new StopWatch(); // Declare a StopWatch instance stopWatch.start();//Task start … stopWatch.stop(); // Task stops return context; }
Looking at the SpringBoot example, we can know that the use of StopWatch is basically divided into three steps: creating an instance, starting and stopping. But as a spring tool class, will StopWatch be so simple? of course not.
Let’s take a look at the specific usage:
public static void main(String[] args) { // The parameters of the constructor method represent the id of the StopWatch instance, marking the identity of the instance. StopWatch watch = new StopWatch("StopWatch-Learning"); String id = watch.getId(); System.out.println("StopWatch's id: " + id); //Start the task, test is the name of the task watch.start("test"); // Get whether StopWatch is running boolean running = watch.isRunning(); System.out.println("Is it running" + running); //Task stops watch.stop(); // Get the name of the task String lastTaskName = watch.getLastTaskName(); System.out.println("StopWatch task name: " + lastTaskName); long lastTaskTimeNanos = watch.getLastTaskTimeNanos();//Task running time nanoseconds // long lastTaskTimeMillis = watch.getLastTaskTimeMillis(); // Task running time in seconds System.out.println("Task" + lastTaskName + "Run" + lastTaskTimeNanos + "ns"); }
operation result:
StopWatch id: StopWatch-Learning is running true StopWatch task name: test Task test ran for 29000ns
We can also define two tasks at the same time:
public static void main(String[] args) { // The parameters of the constructor method represent the id of the StopWatch instance, marking the identity of the instance. StopWatch watch = new StopWatch("StopWatch-Learning"); watch.start("test1"); //Task stops watch.stop(); // Get the name of the task String lastTaskName = watch.getLastTaskName(); long task1TimeNanos = watch.getLastTaskTimeNanos(); // Task running time in nanoseconds // long lastTaskTimeMillis = watch.getLastTaskTimeMillis(); // Task running time in seconds System.out.println("task1" + lastTaskName + "Run" + task1TimeNanos + "ns"); watch.start("test2"); watch.stop(); long task2TimeNanos = watch.getLastTaskTimeNanos(); System.out.println("task2" + lastTaskName + "Run" + task2TimeNanos + "ns"); int count = watch.getTaskCount(); System.out.println("A total of tasks started" + count + "tasks"); long totalTimeNanos = watch.getTotalTimeNanos(); System.out.println("A total of runs" + totalTimeNanos + "ns"); }
operation result:
task1test1 ran for 2200ns task2test1 ran for 300ns A total of 2 tasks were started It ran for a total of 2500ns StopWatch 'StopWatch-Learning': running time = 2500 ns
By the way, there is also a method prettyPrint(), which can help us print the output statements more beautifully!
public static void main(String[] args) { // The parameters of the constructor method represent the id of the StopWatch instance, marking the identity of the instance. StopWatch watch = new StopWatch("StopWatch-Learning"); watch.start("test1"); //Task stops watch.stop(); // Get the name of the task String lastTaskName = watch.getLastTaskName(); long task1TimeNanos = watch.getLastTaskTimeNanos(); // Task running time in nanoseconds // long lastTaskTimeMillis = watch.getLastTaskTimeMillis(); // Task running time in seconds System.out.println("task1" + lastTaskName + "Run" + task1TimeNanos + "ns"); System.out.println("^^^^^^^^^^^^^^^^^^^Separating line^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^"); String info = watch.prettyPrint(); System.out.println(info); }
operation result:
task1test1 ran for 2200ns ^^^^^^^^^^^^^^^^^^^^Dividing line^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ StopWatch 'StopWatch-Learning': running time = 2200 ns ---------------------------------------- ns % Task name ---------------------------------------- 000002200 100% test1
Isn’t it very convenient to use, silky smooth and very clear?
Principle
Let’s take a look at the start() method:
public void start(String taskName) throws IllegalStateException { if (this.currentTaskName != null) { throw new IllegalStateException("Can't start StopWatch: it's already running"); } this.currentTaskName = taskName; this.startTimeNanos = System.nanoTime(); }
At the beginning of the task, System.nanoTime() was used to obtain the nanosecond timestamp of the current time. In fact, it is the same as we used System.currentTimeMillis() before.
Let’s take a look at the stop() method:
public void stop() throws IllegalStateException { if (this.currentTaskName == null) { throw new IllegalStateException("Can't stop StopWatch: it's not running"); } long lastTime = System.nanoTime() - this.startTimeNanos; this.totalTimeNanos + = lastTime; this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime); if (this.keepTaskList) { this.taskList.add(this.lastTaskInfo); } + + this.taskCount; this.currentTaskName = null; }
It is also the time difference calculated by getting the current time and subtracting the start time. It is essentially the same as the currentTimeMillis we talked about at the beginning. It’s just that its time granularity is even finer, at the nanosecond level.
Suddenly there was a feeling of enlightenment. Isn’t this the same method as the one mentioned at the beginning? Isn’t it a modified version of currentTimeMillis? But just because the transformation is very good, we can calculate the task time very simply and cleverly.
The most ingenious thing is that we can create an ID for StopWatch to mark its identity, give each task a name, start and stop at any time, automatically calculate each task, the time difference of all tasks, and automatically format the results. API is more beautiful and grand. During development, it is easy to misunderstand the calculation time of multi-tasks, resulting in inaccurate calculations, and the advantages of StopWatch for multi-tasks are even more obvious.
Since StopWatch is so easy to use, what are you waiting for? Why not get up? That’s it for today’s sharing. There will be more technical sharing in the future. Everyone is welcome to pay attention!
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 138106 people are learning the system