一个简单的任务执行时间监视器 StopWatch

 有时我们在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,然后这样如果执行大量测试的话就很麻烦,并且不直观,

如果想对执行的时间做进一步控制,则需要在程序中很多地方修改,目前spring-framework提供了一个StopWatch类可以做类似任务执行时间控制,也就是封装了一个对开始时间,

结束时间记录操作的Java类,当然还有一些其他控制。源码如下:

/* 
 * Copyright 2002-2010 the original author or authors. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */  
  
package com.test;  
  
import java.text.NumberFormat;  
import java.util.LinkedList;  
import java.util.List;  
  
/** 
 * Simple stop watch, allowing for timing of a number of tasks, 
 * exposing total running time and running time for each named task. 
 * 
 * <p>Conceals use of <code>System.currentTimeMillis()</code>, improving the 
 * readability of application code and reducing the likelihood of calculation errors. 
 * 
 * <p>Note that this object is not designed to be thread-safe and does not 
 * use synchronization. 
 * 
 * <p>This class is normally used to verify performance during proof-of-concepts 
 * and in development, rather than as part of production applications. 
 * 
 * @author Rod Johnson 
 * @author Juergen Hoeller 
 * @author Sam Brannen 
 * @since May 2, 2001 
 */  
public class StopWatch {  
  
    /** 
     * Identifier of this stop watch. 
     * Handy when we have output from multiple stop watches 
     * and need to distinguish between them in log or console output. 
     */  
    private final String id;  
  
    private boolean keepTaskList = true;  
  
    private final List<TaskInfo> taskList = new LinkedList<TaskInfo>();  
  
    /** Start time of the current task */  
    private long startTimeMillis;  
  
    /** Is the stop watch currently running? */  
    private boolean running;  
  
    /** Name of the current task */  
    private String currentTaskName;  
  
    private TaskInfo lastTaskInfo;  
  
    private int taskCount;  
  
    /** Total running time */  
    private long totalTimeMillis;  
  
  
    /** 
     * Construct a new stop watch. Does not start any task. 
     */  
    public StopWatch() {  
        this.id = "";  
    }  
  
    /** 
     * Construct a new stop watch with the given id. 
     * Does not start any task. 
     * @param id identifier for this stop watch. 
     * Handy when we have output from multiple stop watches 
     * and need to distinguish between them. 
     */  
    public StopWatch(String id) {  
        this.id = id;  
    }  
  
  
    /** 
     * Determine whether the TaskInfo array is built over time. Set this to 
     * "false" when using a StopWatch for millions of intervals, or the task 
     * info structure will consume excessive memory. Default is "true". 
     */  
    public void setKeepTaskList(boolean keepTaskList) {  
        this.keepTaskList = keepTaskList;  
    }  
  
  
    /** 
     * Start an unnamed task. The results are undefined if {@link #stop()} 
     * or timing methods are called without invoking this method. 
     * @see #stop() 
     */  
    public void start() throws IllegalStateException {  
        start("");  
    }  
  
    /** 
     * Start a named task. The results are undefined if {@link #stop()} 
     * or timing methods are called without invoking this method. 
     * @param taskName the name of the task to start 
     * @see #stop() 
     */  
    public void start(String taskName) throws IllegalStateException {  
        if (this.running) {  
            throw new IllegalStateException("Can't start StopWatch: it's already running");  
        }  
        this.startTimeMillis = System.currentTimeMillis();  
        this.running = true;  
        this.currentTaskName = taskName;  
    }  
  
    /** 
     * Stop the current task. The results are undefined if timing 
     * methods are called without invoking at least one pair 
     * {@link #start()} / {@link #stop()} methods. 
     * @see #start() 
     */  
    public void stop() throws IllegalStateException {  
        if (!this.running) {  
            throw new IllegalStateException("Can't stop StopWatch: it's not running");  
        }  
        long lastTime = System.currentTimeMillis() - this.startTimeMillis;  
        this.totalTimeMillis += lastTime;  
        this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);  
        if (this.keepTaskList) {  
            this.taskList.add(lastTaskInfo);  
        }  
        ++this.taskCount;  
        this.running = false;  
        this.currentTaskName = null;  
    }  
  
    /** 
     * Return whether the stop watch is currently running. 
     */  
    public boolean isRunning() {  
        return this.running;  
    }  
  
  
    /** 
     * Return the time taken by the last task. 
     */  
    public long getLastTaskTimeMillis() throws IllegalStateException {  
        if (this.lastTaskInfo == null) {  
            throw new IllegalStateException("No tasks run: can't get last task interval");  
        }  
        return this.lastTaskInfo.getTimeMillis();  
    }  
  
    /** 
     * Return the name of the last task. 
     */  
    public String getLastTaskName() throws IllegalStateException {  
        if (this.lastTaskInfo == null) {  
            throw new IllegalStateException("No tasks run: can't get last task name");  
        }  
        return this.lastTaskInfo.getTaskName();  
    }  
  
    /** 
     * Return the last task as a TaskInfo object. 
     */  
    public TaskInfo getLastTaskInfo() throws IllegalStateException {  
        if (this.lastTaskInfo == null) {  
            throw new IllegalStateException("No tasks run: can't get last task info");  
        }  
        return this.lastTaskInfo;  
    }  
  
  
    /** 
     * Return the total time in milliseconds for all tasks. 
     */  
    public long getTotalTimeMillis() {  
        return this.totalTimeMillis;  
    }  
  
    /** 
     * Return the total time in seconds for all tasks. 
     */  
    public double getTotalTimeSeconds() {  
        return this.totalTimeMillis / 1000.0;  
    }  
  
    /** 
     * Return the number of tasks timed. 
     */  
    public int getTaskCount() {  
        return this.taskCount;  
    }  
  
    /** 
     * Return an array of the data for tasks performed. 
     */  
    public TaskInfo[] getTaskInfo() {  
        if (!this.keepTaskList) {  
            throw new UnsupportedOperationException("Task info is not being kept!");  
        }  
        return this.taskList.toArray(new TaskInfo[this.taskList.size()]);  
    }  
  
  
    /** 
     * Return a short description of the total running time. 
     */  
    public String shortSummary() {  
        return "StopWatch '" + this.id + "': running time (millis) = " + getTotalTimeMillis();  
    }  
  
    /** 
     * Return a string with a table describing all tasks performed. 
     * For custom reporting, call getTaskInfo() and use the task info directly. 
     */  
    public String prettyPrint() {  
        StringBuilder sb = new StringBuilder(shortSummary());  
        sb.append('
');  
        if (!this.keepTaskList) {  
            sb.append("No task info kept");  
        } else {  
            sb.append("-----------------------------------------
");  
            sb.append("ms     %     Task name
");  
            sb.append("-----------------------------------------
");  
            NumberFormat nf = NumberFormat.getNumberInstance();  
            nf.setMinimumIntegerDigits(5);  
            nf.setGroupingUsed(false);  
            NumberFormat pf = NumberFormat.getPercentInstance();  
            pf.setMinimumIntegerDigits(3);  
            pf.setGroupingUsed(false);  
            for (TaskInfo task : getTaskInfo()) {  
                sb.append(nf.format(task.getTimeMillis())).append("  ");  
                sb.append(pf.format(task.getTimeSeconds() / getTotalTimeSeconds())).append("  ");  
                sb.append(task.getTaskName()).append("
");  
            }  
        }  
        return sb.toString();  
    }  
  
    /** 
     * Return an informative string describing all tasks performed 
     * For custom reporting, call <code>getTaskInfo()</code> and use the task info directly. 
     */  
    @Override  
    public String toString() {  
        StringBuilder sb = new StringBuilder(shortSummary());  
        if (this.keepTaskList) {  
            for (TaskInfo task : getTaskInfo()) {  
                sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeMillis());  
                long percent = Math.round((100.0 * task.getTimeSeconds()) / getTotalTimeSeconds());  
                sb.append(" = ").append(percent).append("%");  
            }  
        } else {  
            sb.append("; no task info kept");  
        }  
        return sb.toString();  
    }  
  
  
    /** 
     * Inner class to hold data about one task executed within the stop watch. 
     */  
    public static final class TaskInfo {  
  
        private final String taskName;  
  
        private final long timeMillis;  
  
        TaskInfo(String taskName, long timeMillis) {  
            this.taskName = taskName;  
            this.timeMillis = timeMillis;  
        }  
  
        /** 
         * Return the name of this task. 
         */  
        public String getTaskName() {  
            return this.taskName;  
        }  
  
        /** 
         * Return the time in milliseconds this task took. 
         */  
        public long getTimeMillis() {  
            return this.timeMillis;  
        }  
  
        /** 
         * Return the time in seconds this task took. 
         */  
        public double getTimeSeconds() {  
            return this.timeMillis / 1000.0;  
        }  
    }  
      
    /** 
     * test 
     * @throws InterruptedException  
     */  
    public static void main(String[] args) throws InterruptedException{  
        StopWatch first = new StopWatch("First");  
        first.start("A");  
        Thread.sleep(200);  
        first.stop();  
        first.start("B");  
        Thread.sleep(200);  
        first.stop();  
        first.start("C");  
        Thread.sleep(120);  
        first.stop();  
        System.out.println(first.prettyPrint());  
          
    }  
}  
View Code

执行结果如下:

 
  1. StopWatch 'First': running time (millis) = 516  
  2. -----------------------------------------  
  3. ms     %     Task name  
  4. -----------------------------------------  
  5. 00203  039%  A  
  6. 00203  039%  B  
  7. 00110  021%  C  

打印每个任务执行时间,以及占总时间百分比,个人开发测试时挺有用的,可以作为小工具收藏。

原文地址:https://www.cnblogs.com/xingzc/p/5993694.html