zoukankan      html  css  js  c++  java
  • 计时器StopWatch的几种写法

    下面提供三种计时器的写法供大家参考,大家可以自行选择自己钟爱的使用。

    写法一(Spring 包提供的计时器):

      1 import java.text.NumberFormat;
      2 import java.util.LinkedList;
      3 import java.util.List;
      4 
      5 /**
      6  * Simple stop watch, allowing for timing of a number of tasks,
      7  * exposing total running time and running time for each named task.
      8  *
      9  * <p>Conceals use of {@code System.currentTimeMillis()}, improving the
     10  * readability of application code and reducing the likelihood of calculation errors.
     11  *
     12  * <p>Note that this object is not designed to be thread-safe and does not
     13  * use synchronization.
     14  *
     15  * <p>This class is normally used to verify performance during proof-of-concepts
     16  * and in development, rather than as part of production applications.
     17  *
     18  * @author Rod Johnson
     19  * @author Juergen Hoeller
     20  * @author Sam Brannen
     21  * @since May 2, 2001
     22  */
     23 public class StopWatch {
     24 
     25     /**
     26      * Identifier of this stop watch.
     27      * Handy when we have output from multiple stop watches
     28      * and need to distinguish between them in log or console output.
     29      */
     30     private final String id;
     31 
     32     private boolean keepTaskList = true;
     33 
     34     private final List<TaskInfo> taskList = new LinkedList<TaskInfo>();
     35 
     36     /** Start time of the current task */
     37     private long startTimeMillis;
     38 
     39     /** Is the stop watch currently running? */
     40     private boolean running;
     41 
     42     /** Name of the current task */
     43     private String currentTaskName;
     44 
     45     private TaskInfo lastTaskInfo;
     46 
     47     private int taskCount;
     48 
     49     /** Total running time */
     50     private long totalTimeMillis;
     51 
     52 
     53     /**
     54      * Construct a new stop watch. Does not start any task.
     55      */
     56     public StopWatch() {
     57         this("");
     58     }
     59 
     60     /**
     61      * Construct a new stop watch with the given id.
     62      * Does not start any task.
     63      * @param id identifier for this stop watch.
     64      * Handy when we have output from multiple stop watches
     65      * and need to distinguish between them.
     66      */
     67     public StopWatch(String id) {
     68         this.id = id;
     69     }
     70 
     71 
     72     /**
     73      * Return the id of this stop watch, as specified on construction.
     74      * @return the id (empty String by default)
     75      * @since 4.2.2
     76      * @see #StopWatch(String)
     77      */
     78     public String getId() {
     79         return this.id;
     80     }
     81 
     82     /**
     83      * Determine whether the TaskInfo array is built over time. Set this to
     84      * "false" when using a StopWatch for millions of intervals, or the task
     85      * info structure will consume excessive memory. Default is "true".
     86      */
     87     public void setKeepTaskList(boolean keepTaskList) {
     88         this.keepTaskList = keepTaskList;
     89     }
     90 
     91 
     92     /**
     93      * Start an unnamed task. The results are undefined if {@link #stop()}
     94      * or timing methods are called without invoking this method.
     95      * @see #stop()
     96      */
     97     public void start() throws IllegalStateException {
     98         start("");
     99     }
    100 
    101     /**
    102      * Start a named task. The results are undefined if {@link #stop()}
    103      * or timing methods are called without invoking this method.
    104      * @param taskName the name of the task to start
    105      * @see #stop()
    106      */
    107     public void start(String taskName) throws IllegalStateException {
    108         if (this.running) {
    109             throw new IllegalStateException("Can't start StopWatch: it's already running");
    110         }
    111         this.running = true;
    112         this.currentTaskName = taskName;
    113         this.startTimeMillis = System.currentTimeMillis();
    114     }
    115 
    116     /**
    117      * Stop the current task. The results are undefined if timing
    118      * methods are called without invoking at least one pair
    119      * {@code start()} / {@code stop()} methods.
    120      * @see #start()
    121      */
    122     public void stop() throws IllegalStateException {
    123         if (!this.running) {
    124             throw new IllegalStateException("Can't stop StopWatch: it's not running");
    125         }
    126         long lastTime = System.currentTimeMillis() - this.startTimeMillis;
    127         this.totalTimeMillis += lastTime;
    128         this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
    129         if (this.keepTaskList) {
    130             this.taskList.add(lastTaskInfo);
    131         }
    132         ++this.taskCount;
    133         this.running = false;
    134         this.currentTaskName = null;
    135     }
    136 
    137     /**
    138      * Return whether the stop watch is currently running.
    139      * @see #currentTaskName()
    140      */
    141     public boolean isRunning() {
    142         return this.running;
    143     }
    144 
    145     /**
    146      * Return the name of the currently running task, if any.
    147      * @since 4.2.2
    148      * @see #isRunning()
    149      */
    150     public String currentTaskName() {
    151         return this.currentTaskName;
    152     }
    153 
    154 
    155     /**
    156      * Return the time taken by the last task.
    157      */
    158     public long getLastTaskTimeMillis() throws IllegalStateException {
    159         if (this.lastTaskInfo == null) {
    160             throw new IllegalStateException("No tasks run: can't get last task interval");
    161         }
    162         return this.lastTaskInfo.getTimeMillis();
    163     }
    164 
    165     /**
    166      * Return the name of the last task.
    167      */
    168     public String getLastTaskName() throws IllegalStateException {
    169         if (this.lastTaskInfo == null) {
    170             throw new IllegalStateException("No tasks run: can't get last task name");
    171         }
    172         return this.lastTaskInfo.getTaskName();
    173     }
    174 
    175     /**
    176      * Return the last task as a TaskInfo object.
    177      */
    178     public TaskInfo getLastTaskInfo() throws IllegalStateException {
    179         if (this.lastTaskInfo == null) {
    180             throw new IllegalStateException("No tasks run: can't get last task info");
    181         }
    182         return this.lastTaskInfo;
    183     }
    184 
    185 
    186     /**
    187      * Return the total time in milliseconds for all tasks.
    188      */
    189     public long getTotalTimeMillis() {
    190         return this.totalTimeMillis;
    191     }
    192 
    193     /**
    194      * Return the total time in seconds for all tasks.
    195      */
    196     public double getTotalTimeSeconds() {
    197         return this.totalTimeMillis / 1000.0;
    198     }
    199 
    200     /**
    201      * Return the number of tasks timed.
    202      */
    203     public int getTaskCount() {
    204         return this.taskCount;
    205     }
    206 
    207     /**
    208      * Return an array of the data for tasks performed.
    209      */
    210     public TaskInfo[] getTaskInfo() {
    211         if (!this.keepTaskList) {
    212             throw new UnsupportedOperationException("Task info is not being kept!");
    213         }
    214         return this.taskList.toArray(new TaskInfo[this.taskList.size()]);
    215     }
    216 
    217 
    218     /**
    219      * Return a short description of the total running time.
    220      */
    221     public String shortSummary() {
    222         return "StopWatch '" + getId() + "': running time (millis) = " + getTotalTimeMillis();
    223     }
    224 
    225     /**
    226      * Return a string with a table describing all tasks performed.
    227      * For custom reporting, call getTaskInfo() and use the task info directly.
    228      */
    229     public String prettyPrint() {
    230         StringBuilder sb = new StringBuilder(shortSummary());
    231         sb.append('
    ');
    232         if (!this.keepTaskList) {
    233             sb.append("No task info kept");
    234         }
    235         else {
    236             sb.append("-----------------------------------------
    ");
    237             sb.append("ms     %     Task name
    ");
    238             sb.append("-----------------------------------------
    ");
    239             NumberFormat nf = NumberFormat.getNumberInstance();
    240             nf.setMinimumIntegerDigits(5);
    241             nf.setGroupingUsed(false);
    242             NumberFormat pf = NumberFormat.getPercentInstance();
    243             pf.setMinimumIntegerDigits(3);
    244             pf.setGroupingUsed(false);
    245             for (TaskInfo task : getTaskInfo()) {
    246                 sb.append(nf.format(task.getTimeMillis())).append("  ");
    247                 sb.append(pf.format(task.getTimeSeconds() / getTotalTimeSeconds())).append("  ");
    248                 sb.append(task.getTaskName()).append("
    ");
    249             }
    250         }
    251         return sb.toString();
    252     }
    253 
    254     /**
    255      * Return an informative string describing all tasks performed
    256      * For custom reporting, call {@code getTaskInfo()} and use the task info directly.
    257      */
    258     @Override
    259     public String toString() {
    260         StringBuilder sb = new StringBuilder(shortSummary());
    261         if (this.keepTaskList) {
    262             for (TaskInfo task : getTaskInfo()) {
    263                 sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeMillis());
    264                 long percent = Math.round((100.0 * task.getTimeSeconds()) / getTotalTimeSeconds());
    265                 sb.append(" = ").append(percent).append("%");
    266             }
    267         }
    268         else {
    269             sb.append("; no task info kept");
    270         }
    271         return sb.toString();
    272     }
    273 
    274 
    275     /**
    276      * Inner class to hold data about one task executed within the stop watch.
    277      */
    278     public static final class TaskInfo {
    279 
    280         private final String taskName;
    281 
    282         private final long timeMillis;
    283 
    284         TaskInfo(String taskName, long timeMillis) {
    285             this.taskName = taskName;
    286             this.timeMillis = timeMillis;
    287         }
    288 
    289         /**
    290          * Return the name of this task.
    291          */
    292         public String getTaskName() {
    293             return this.taskName;
    294         }
    295 
    296         /**
    297          * Return the time in milliseconds this task took.
    298          */
    299         public long getTimeMillis() {
    300             return this.timeMillis;
    301         }
    302 
    303         /**
    304          * Return the time in seconds this task took.
    305          */
    306         public double getTimeSeconds() {
    307             return (this.timeMillis / 1000.0);
    308         }
    309     }
    310 
    311 }

    下面写一个调用:

    public static void main(String[] args) throws InterruptedException {
    //        StopWatchTest.test0();
         StopWatchTest.test1();
    }
    
    public static void test1() throws InterruptedException {
         StopWatch sw = new StopWatch("test");
         sw.start("task1");
         // do something
        Thread.sleep(100);
        sw.stop();
        sw.start("task2");
        // do something
        Thread.sleep(200);
        sw.stop();
        System.out.println("sw.prettyPrint()~~~~~~~~~~~~~~~~~");
        System.out.println(sw.prettyPrint());
    }
    运行结果:
    sw.prettyPrint()~~~~~~~~~~~~~~~~~
    StopWatch 'test': running time (millis) = 308
    -----------------------------------------
    ms     %     Task name
    -----------------------------------------
    00104  034%  task1
    00204  066%  task2
    --------------------- 
    

      start开始记录,stop停止记录,然后通过StopWatch的prettyPrint方法,可直观的输出代码执行耗时,以及执行时间百分比,瞬间感觉比之前的方式高大上了一个档次。

     除此之外,还有以下两个方法shortSummary,getTotalTimeMillis,查看程序执行时间。

    写法二(apache.commons实现的计时器):

    import java.util.concurrent.TimeUnit;
    
    /**
     * <p>
     * <code>StopWatch</code> provides a convenient API for timings.
     * </p>
     *
     * <p>
     * To start the watch, call {@link #start()} or {@link StopWatch#createStarted()}. At this point you can:
     * </p>
     * <ul>
     * <li>{@link #split()} the watch to get the time whilst the watch continues in the background. {@link #unsplit()} will
     * remove the effect of the split. At this point, these three options are available again.</li>
     * <li>{@link #suspend()} the watch to pause it. {@link #resume()} allows the watch to continue. Any time between the
     * suspend and resume will not be counted in the total. At this point, these three options are available again.</li>
     * <li>{@link #stop()} the watch to complete the timing session.</li>
     * </ul>
     *
     * <p>
     * It is intended that the output methods {@link #toString()} and {@link #getTime()} should only be called after stop,
     * split or suspend, however a suitable result will be returned at other points.
     * </p>
     *
     * <p>
     * NOTE: As from v2.1, the methods protect against inappropriate calls. Thus you cannot now call stop before start,
     * resume before suspend or unsplit before split.
     * </p>
     *
     * <p>
     * 1. split(), suspend(), or stop() cannot be invoked twice<br>
     * 2. unsplit() may only be called if the watch has been split()<br>
     * 3. resume() may only be called if the watch has been suspend()<br>
     * 4. start() cannot be called twice without calling reset()
     * </p>
     *
     * <p>This class is not thread-safe</p>
     *
     * @since 2.0
     */
    public class StopWatch {
    
        private static final long NANO_2_MILLIS = 1000000L;
    
    
        /**
         * Provides a started stopwatch for convenience.
         *
         * @return StopWatch a stopwatch that's already been started.
         *
         * @since 3.5
         */
        public static StopWatch createStarted() {
            final StopWatch sw = new StopWatch();
            sw.start();
            return sw;
        }
    
        /**
         * Enumeration type which indicates the status of stopwatch.
         */
        private enum State {
    
            UNSTARTED {
                @Override
                boolean isStarted() {
                    return false;
                }
                @Override
                boolean isStopped() {
                    return true;
                }
                @Override
                boolean isSuspended() {
                    return false;
                }
            },
            RUNNING {
                @Override
                boolean isStarted() {
                    return true;
                }
                @Override
                boolean isStopped() {
                    return false;
                }
                @Override
                boolean isSuspended() {
                    return false;
                }
            },
            STOPPED {
                @Override
                boolean isStarted() {
                    return false;
                }
                @Override
                boolean isStopped() {
                    return true;
                }
                @Override
                boolean isSuspended() {
                    return false;
                }
            },
            SUSPENDED {
                @Override
                boolean isStarted() {
                    return true;
                }
                @Override
                boolean isStopped() {
                    return false;
                }
                @Override
                boolean isSuspended() {
                    return true;
                }
            };
    
            /**
             * <p>
             * The method is used to find out if the StopWatch is started. A suspended
             * StopWatch is also started watch.
             * </p>
    
             * @return boolean
             *             If the StopWatch is started.
             */
            abstract boolean isStarted();
    
            /**
             * <p>
             * This method is used to find out whether the StopWatch is stopped. The
             * stopwatch which's not yet started and explicitly stopped stopwatch is
             * considered as stopped.
             * </p>
             *
             * @return boolean
             *             If the StopWatch is stopped.
             */
            abstract boolean isStopped();
    
            /**
             * <p>
             * This method is used to find out whether the StopWatch is suspended.
             * </p>
             *
             * @return boolean
             *             If the StopWatch is suspended.
             */
            abstract boolean isSuspended();
        }
    
        /**
         * Enumeration type which indicates the split status of stopwatch.
         */
        private enum SplitState {
            SPLIT,
            UNSPLIT
        }
        /**
         * The current running state of the StopWatch.
         */
        private State runningState = State.UNSTARTED;
    
        /**
         * Whether the stopwatch has a split time recorded.
         */
        private SplitState splitState = SplitState.UNSPLIT;
    
        /**
         * The start time.
         */
        private long startTime;
    
        /**
         * The start time in Millis - nanoTime is only for elapsed time so we
         * need to also store the currentTimeMillis to maintain the old
         * getStartTime API.
         */
        private long startTimeMillis;
    
        /**
         * The stop time.
         */
        private long stopTime;
    
        /**
         * <p>
         * Constructor.
         * </p>
         */
        public StopWatch() {
            super();
        }
    
        /**
         * <p>
         * Start the stopwatch.
         * </p>
         *
         * <p>
         * This method starts a new timing session, clearing any previous values.
         * </p>
         *
         * @throws IllegalStateException
         *             if the StopWatch is already running.
         */
        public void start() {
            if (this.runningState == State.STOPPED) {
                throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
            }
            if (this.runningState != State.UNSTARTED) {
                throw new IllegalStateException("Stopwatch already started. ");
            }
            this.startTime = System.nanoTime();
            this.startTimeMillis = System.currentTimeMillis();
            this.runningState = State.RUNNING;
        }
    
    
        /**
         * <p>
         * Stop the stopwatch.
         * </p>
         *
         * <p>
         * This method ends a new timing session, allowing the time to be retrieved.
         * </p>
         *
         * @throws IllegalStateException
         *             if the StopWatch is not running.
         */
        public void stop() {
            if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
                throw new IllegalStateException("Stopwatch is not running. ");
            }
            if (this.runningState == State.RUNNING) {
                this.stopTime = System.nanoTime();
            }
            this.runningState = State.STOPPED;
        }
    
        /**
         * <p>
         * Resets the stopwatch. Stops it if need be.
         * </p>
         *
         * <p>
         * This method clears the internal values to allow the object to be reused.
         * </p>
         */
        public void reset() {
            this.runningState = State.UNSTARTED;
            this.splitState = SplitState.UNSPLIT;
        }
    
        /**
         * <p>
         * Split the time.
         * </p>
         *
         * <p>
         * This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected,
         * enabling {@link #unsplit()} to continue the timing from the original start point.
         * </p>
         *
         * @throws IllegalStateException
         *             if the StopWatch is not running.
         */
        public void split() {
            if (this.runningState != State.RUNNING) {
                throw new IllegalStateException("Stopwatch is not running. ");
            }
            this.stopTime = System.nanoTime();
            this.splitState = SplitState.SPLIT;
        }
    
        /**
         * <p>
         * Remove a split.
         * </p>
         *
         * <p>
         * This method clears the stop time. The start time is unaffected, enabling timing from the original start point to
         * continue.
         * </p>
         *
         * @throws IllegalStateException
         *             if the StopWatch has not been split.
         */
        public void unsplit() {
            if (this.splitState != SplitState.SPLIT) {
                throw new IllegalStateException("Stopwatch has not been split. ");
            }
            this.splitState = SplitState.UNSPLIT;
        }
    
        /**
         * <p>
         * Suspend the stopwatch for later resumption.
         * </p>
         *
         * <p>
         * This method suspends the watch until it is resumed. The watch will not include time between the suspend and
         * resume calls in the total time.
         * </p>
         *
         * @throws IllegalStateException
         *             if the StopWatch is not currently running.
         */
        public void suspend() {
            if (this.runningState != State.RUNNING) {
                throw new IllegalStateException("Stopwatch must be running to suspend. ");
            }
            this.stopTime = System.nanoTime();
            this.runningState = State.SUSPENDED;
        }
    
        /**
         * <p>
         * Resume the stopwatch after a suspend.
         * </p>
         *
         * <p>
         * This method resumes the watch after it was suspended. The watch will not include time between the suspend and
         * resume calls in the total time.
         * </p>
         *
         * @throws IllegalStateException
         *             if the StopWatch has not been suspended.
         */
        public void resume() {
            if (this.runningState != State.SUSPENDED) {
                throw new IllegalStateException("Stopwatch must be suspended to resume. ");
            }
            this.startTime += System.nanoTime() - this.stopTime;
            this.runningState = State.RUNNING;
        }
    
        /**
         * <p>
         * Get the time on the stopwatch.
         * </p>
         *
         * <p>
         * This is either the time between the start and the moment this method is called, or the amount of time between
         * start and stop.
         * </p>
         *
         * @return the time in milliseconds
         */
        public long getTime() {
            return getNanoTime() / NANO_2_MILLIS;
        }
    
        /**
         * <p>
         * Get the time on the stopwatch in the specified TimeUnit.
         * </p>
         *
         * <p>
         * This is either the time between the start and the moment this method is called, or the amount of time between
         * start and stop. The resulting time will be expressed in the desired TimeUnit with any remainder rounded down.
         * For example, if the specified unit is {@code TimeUnit.HOURS} and the stopwatch time is 59 minutes, then the
         * result returned will be {@code 0}.
         * </p>
         *
         * @param timeUnit the unit of time, not null
         * @return the time in the specified TimeUnit, rounded down
         * @since 3.5
         */
        public long getTime(final TimeUnit timeUnit) {
            return timeUnit.convert(getNanoTime(), TimeUnit.NANOSECONDS);
        }
    
        /**
         * <p>
         * Get the time on the stopwatch in nanoseconds.
         * </p>
         *
         * <p>
         * This is either the time between the start and the moment this method is called, or the amount of time between
         * start and stop.
         * </p>
         *
         * @return the time in nanoseconds
         * @since 3.0
         */
        public long getNanoTime() {
            if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) {
                return this.stopTime - this.startTime;
            } else if (this.runningState == State.UNSTARTED) {
                return 0;
            } else if (this.runningState == State.RUNNING) {
                return System.nanoTime() - this.startTime;
            }
            throw new RuntimeException("Illegal running state has occurred.");
        }
    
        /**
         * <p>
         * Get the split time on the stopwatch.
         * </p>
         *
         * <p>
         * This is the time between start and latest split.
         * </p>
         *
         * @return the split time in milliseconds
         *
         * @throws IllegalStateException
         *             if the StopWatch has not yet been split.
         * @since 2.1
         */
        public long getSplitTime() {
            return getSplitNanoTime() / NANO_2_MILLIS;
        }
        /**
         * <p>
         * Get the split time on the stopwatch in nanoseconds.
         * </p>
         *
         * <p>
         * This is the time between start and latest split.
         * </p>
         *
         * @return the split time in nanoseconds
         *
         * @throws IllegalStateException
         *             if the StopWatch has not yet been split.
         * @since 3.0
         */
        public long getSplitNanoTime() {
            if (this.splitState != SplitState.SPLIT) {
                throw new IllegalStateException("Stopwatch must be split to get the split time. ");
            }
            return this.stopTime - this.startTime;
        }
    
        /**
         * Returns the time this stopwatch was started.
         *
         * @return the time this stopwatch was started
         * @throws IllegalStateException
         *             if this StopWatch has not been started
         * @since 2.4
         */
        public long getStartTime() {
            if (this.runningState == State.UNSTARTED) {
                throw new IllegalStateException("Stopwatch has not been started");
            }
            // System.nanoTime is for elapsed time
            return this.startTimeMillis;
        }
    
        /**
         * <p>
         * Gets a summary of the time that the stopwatch recorded as a string.
         * </p>
         *
         * <p>
         * The format used is ISO 8601-like, <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.
         * </p>
         *
         * @return the time as a String
         */
        @Override
        public String toString() {
            return DurationFormatUtils.formatDurationHMS(getTime());
        }
    
        /**
         * <p>
         * Gets a summary of the split time that the stopwatch recorded as a string.
         * </p>
         *
         * <p>
         * The format used is ISO 8601-like, <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.
         * </p>
         *
         * @return the split time as a String
         * @since 2.1
         */
        public String toSplitString() {
            return DurationFormatUtils.formatDurationHMS(getSplitTime());
        }
    
        /**
         * <p>
         * The method is used to find out if the StopWatch is started. A suspended
         * StopWatch is also started watch.
         * </p>
         *
         * @return boolean
         *             If the StopWatch is started.
         * @since 3.2
         */
        public boolean isStarted() {
            return runningState.isStarted();
        }
    
        /**
         * <p>
         * This method is used to find out whether the StopWatch is suspended.
         * </p>
         *
         * @return boolean
         *             If the StopWatch is suspended.
         * @since 3.2
         */
        public boolean isSuspended() {
            return runningState.isSuspended();
        }
    
        /**
         * <p>
         * This method is used to find out whether the StopWatch is stopped. The
         * stopwatch which's not yet started and explicitly stopped stopwatch is
         * considered as stopped.
         * </p>
         *
         * @return boolean
         *             If the StopWatch is stopped.
         * @since 3.2
         */
        public boolean isStopped() {
            return runningState.isStopped();
        }
    
    }

    写法三(Scala函数写法):

    import org.slf4j.LoggerFactory
    
    /**
      * 类功能描述:Debug日志追踪
      *
      * @author barry create at 18-8-29 下午3:41
      * @version 1.0.0
      */
    object Debug {
      val LOGGER = LoggerFactory.getLogger(getClass)
      val counter = collection.mutable.Map[String, Int]() // label -> count
      val times = collection.mutable.Map[String, Long]() // label - time(ns)
    
      /**
        *追踪代码块
        * @param label 标签名
        * @param codeBlock 代码块
        * @tparam T 返回结果类型
        * @return
        */
      def trace[T](label: String)(codeBlock: => T) = {
        val t0 = System.nanoTime()
        val result = codeBlock
        val t1 = System.nanoTime()
        counter.get(label).map(_counter => counter.put(label, _counter + 1)).orElse(counter.put(label, 1))
        times.get(label).map(cost => times.put(label, cost + (t1 - t0))).orElse(times.put(label, t1 - t0))
        result
      }
    
      /**
        * 打印日志
        */
      def info(): Unit = {
        LOGGER.warn("FinallyDone...")
        LOGGER.warn(s"counter:${counter}")
        LOGGER.warn(s"times:${times.map { case (label, cost) => (label, cost / 1000000)}}ms")
      }
    
      /**
        * 重新计数
        */
      def reset(): Unit = {
        counter.clear()
        times.clear()
      }
    }

    参考下面测试代码:

    java版本:

     1 /**
     2  * @author WangXueXing create at 19-7-31 下午1:46
     3  * @version 1.0.0
     4  */
     5 public class StopWatchDemo {
     6     public static void main(String[] args){
     7         Debug.trace("方法1调用次数及用时", ()->{
     8             try {
     9                 Thread.sleep(2000);
    10             } catch (InterruptedException e) {
    11                 e.printStackTrace();
    12             }
    13             return "";
    14         });
    15         
    16         Debug.trace("方法1调用次数及用时", ()->{
    17             try {
    18                 Thread.sleep(2000);
    19             } catch (InterruptedException e) {
    20                 e.printStackTrace();
    21             }
    22             return "";
    23         });
    24         
    25         Debug.trace("方法2调用次数及用时", ()->{
    26             try {
    27                 Thread.sleep(2000);
    28             } catch (InterruptedException e) {
    29                 e.printStackTrace();
    30             }
    31             return 10;
    32         });
    33 
    34         Debug.info();
    35     }
    36 }

    输出结果:

    15:29:32.228 [main] WARN  test.Debug$ - FinallyDone...
    15:29:32.361 [main] WARN  test.Debug$ - counter:Map(方法2调用次数及用时 -> 1, 方法1调用次数及用时 -> 2)
    15:29:32.364 [main] WARN  test.Debug$ - times:Map(方法2调用次数及用时 -> 2000, 方法1调用次数及用时 -> 4000)ms
    

      

    scala版本:

    /**
      * @author WangXueXing create at 19-8-1 下午3:40
      * @version 1.0.0
      */
    object StopWatchTest {
      def main(args: Array[String]): Unit = {
        Debug.trace("方法1调用次数及用时")( Thread.sleep(200))
        Debug.trace("方法1调用次数及用时")( Thread.sleep(200))
        Debug.trace("方法2调用次数及用时")( Thread.sleep(200))
        Debug.info()
      }
    }

    输出结果:

    15:43:58.601 [main] WARN  test.stopwatch.Debug$ - FinallyDone...
    15:43:58.735 [main] WARN  test.stopwatch.Debug$ - counter:Map(方法2调用次数及用时 -> 1, 方法1调用次数及用时 -> 2)
    15:43:58.739 [main] WARN  test.stopwatch.Debug$ - times:Map(方法2调用次数及用时 -> 200, 方法1调用次数及用时 -> 400)ms
    

      

    对比java版本与scala版本,是不是看到scala的简洁及强大了吧!

  • 相关阅读:
    数据结构与算法之并查集的精简要点总结
    Python/C++ API使用指南 (Python & C++ 混编)
    Visual Studio 动态链接库(dll)文件使用
    C++ 之 多态(虚函数与虚继承)
    Map与Set关于迭代
    Mybatis配置解析
    mybatis入门
    数据结构与算法概念回顾
    利用commons工具包实现文件上传
    JavaWeb开发中的分层思想(一)
  • 原文地址:https://www.cnblogs.com/barrywxx/p/11282215.html
Copyright © 2011-2022 走看看