zoukankan      html  css  js  c++  java
  • 一个简单的任务执行时间监视器 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  

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

  • 相关阅读:
    C++ 归纳复习常规篇
    小技巧:linux启动nginx服务异常 systemctl daemon-reload
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    Migration in EF 6 Code-First
    国外.net资源学习网站
  • 原文地址:https://www.cnblogs.com/xingzc/p/5993694.html
Copyright © 2011-2022 走看看