java stopwatch 功能
C#中有一个stopwatch的功能,主要是用来监测程序执行时间的。java之前一直都在用如下方式完成:
1 public static void main(String[] args) { 2 long startTime=System.currentTimeMillis(); //获取开始时间 3 4 //函数主体代码 5 //... 6 7 long endTime=System.currentTimeMillis(); //获取结束时间 8 System.out.println("程序运行时间: "+(endTime-startTime)+"ms"); 9 10 }
今天上网搜索了一下,找到了一个比较类似的:
1 import org.apache.commons.lang3.time; 2 3 StopWatch watch=new StopWatch(); 4 watch.start(); 5 watch.stop(); 6 watch.getSplitTime();
但是上面的时间处理只支持ms,有些时间比较长还得自己处理,就又找了一个:
1 import java.util.concurrent.TimeUnit; 2 import com.google.common.base.Stopwatch; 3 4 Stopwatch watch = new Stopwatch(); 5 watch.start(); 6 watch.stop(); 7 watch.elapsed(TimeUnit.MINUTES);
时间可以支持多种格式,可以自由选择,但是看了下源码,感觉里面好多方法都是 @Deprecated,估计是比较老的api了:
1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.base; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.base.Preconditions.checkState; 21 import static java.util.concurrent.TimeUnit.MICROSECONDS; 22 import static java.util.concurrent.TimeUnit.MILLISECONDS; 23 import static java.util.concurrent.TimeUnit.NANOSECONDS; 24 import static java.util.concurrent.TimeUnit.SECONDS; 25 26 import com.google.common.annotations.Beta; 27 import com.google.common.annotations.GwtCompatible; 28 import com.google.common.annotations.GwtIncompatible; 29 30 import java.util.concurrent.TimeUnit; 31 32 /** 33 * An object that measures elapsed time in nanoseconds. It is useful to measure 34 * elapsed time using this class instead of direct calls to {@link 35 * System#nanoTime} for a few reasons: 36 * 37 * <ul> 38 * <li>An alternate time source can be substituted, for testing or performance 39 * reasons. 40 * <li>As documented by {@code nanoTime}, the value returned has no absolute 41 * meaning, and can only be interpreted as relative to another timestamp 42 * returned by {@code nanoTime} at a different time. {@code Stopwatch} is a 43 * more effective abstraction because it exposes only these relative values, 44 * not the absolute ones. 45 * </ul> 46 * 47 * <p>Basic usage: 48 * <pre> 49 * Stopwatch stopwatch = new Stopwatch().{@link #start start}(); 50 * doSomething(); 51 * stopwatch.{@link #stop stop}(); // optional 52 * 53 * long millis = stopwatch.elapsed(MILLISECONDS); 54 * 55 * log.info("that took: " + stopwatch); // formatted string like "12.3 ms" 56 * </pre> 57 * 58 * <p>Stopwatch methods are not idempotent; it is an error to start or stop a 59 * stopwatch that is already in the desired state. 60 * 61 * <p>When testing code that uses this class, use the {@linkplain 62 * #Stopwatch(Ticker) alternate constructor} to supply a fake or mock ticker. 63 * <!-- TODO(kevinb): restore the "such as" --> This allows you to 64 * simulate any valid behavior of the stopwatch. 65 * 66 * <p><b>Note:</b> This class is not thread-safe. 67 * 68 * @author Kevin Bourrillion 69 * @since 10.0 70 */ 71 @Beta 72 @GwtCompatible(emulated = true) 73 public final class Stopwatch { 74 private final Ticker ticker; 75 private boolean isRunning; 76 private long elapsedNanos; 77 private long startTick; 78 79 /** 80 * Creates (but does not start) a new stopwatch using {@link System#nanoTime} 81 * as its time source. 82 */ 83 public Stopwatch() { 84 this(Ticker.systemTicker()); 85 } 86 87 /** 88 * Creates (but does not start) a new stopwatch, using the specified time 89 * source. 90 */ 91 public Stopwatch(Ticker ticker) { 92 this.ticker = checkNotNull(ticker, "ticker"); 93 } 94 95 /** 96 * Returns {@code true} if {@link #start()} has been called on this stopwatch, 97 * and {@link #stop()} has not been called since the last call to {@code 98 * start()}. 99 */ 100 public boolean isRunning() { 101 return isRunning; 102 } 103 104 /** 105 * Starts the stopwatch. 106 * 107 * @return this {@code Stopwatch} instance 108 * @throws IllegalStateException if the stopwatch is already running. 109 */ 110 public Stopwatch start() { 111 checkState(!isRunning, 112 "This stopwatch is already running; it cannot be started more than once."); 113 isRunning = true; 114 startTick = ticker.read(); 115 return this; 116 } 117 118 /** 119 * Stops the stopwatch. Future reads will return the fixed duration that had 120 * elapsed up to this point. 121 * 122 * @return this {@code Stopwatch} instance 123 * @throws IllegalStateException if the stopwatch is already stopped. 124 */ 125 public Stopwatch stop() { 126 long tick = ticker.read(); 127 checkState(isRunning, 128 "This stopwatch is already stopped; it cannot be stopped more than once."); 129 isRunning = false; 130 elapsedNanos += tick - startTick; 131 return this; 132 } 133 134 /** 135 * Sets the elapsed time for this stopwatch to zero, 136 * and places it in a stopped state. 137 * 138 * @return this {@code Stopwatch} instance 139 */ 140 public Stopwatch reset() { 141 elapsedNanos = 0; 142 isRunning = false; 143 return this; 144 } 145 146 private long elapsedNanos() { 147 return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos; 148 } 149 150 /** 151 * Returns the current elapsed time shown on this stopwatch, expressed 152 * in the desired time unit, with any fraction rounded down. 153 * 154 * <p>Note that the overhead of measurement can be more than a microsecond, so 155 * it is generally not useful to specify {@link TimeUnit#NANOSECONDS} 156 * precision here. 157 * 158 * @since 14.0 (since 10.0 as {@code elapsedTime()}) 159 */ 160 public long elapsed(TimeUnit desiredUnit) { 161 return desiredUnit.convert(elapsedNanos(), NANOSECONDS); 162 } 163 164 /** 165 * Returns the current elapsed time shown on this stopwatch, expressed 166 * in the desired time unit, with any fraction rounded down. 167 * 168 * <p>Note that the overhead of measurement can be more than a microsecond, so 169 * it is generally not useful to specify {@link TimeUnit#NANOSECONDS} 170 * precision here. 171 * 172 * @deprecated Use {@link Stopwatch#elapsed(TimeUnit)} instead. This method is 173 * scheduled to be removed in Guava release 16.0. 174 */ 175 @Deprecated 176 public long elapsedTime(TimeUnit desiredUnit) { 177 return elapsed(desiredUnit); 178 } 179 180 /** 181 * Returns the current elapsed time shown on this stopwatch, expressed 182 * in milliseconds, with any fraction rounded down. This is identical to 183 * {@code elapsed(TimeUnit.MILLISECONDS)}. 184 * 185 * @deprecated Use {@code stopwatch.elapsed(MILLISECONDS)} instead. This 186 * method is scheduled to be removed in Guava release 16.0. 187 */ 188 @Deprecated 189 public long elapsedMillis() { 190 return elapsed(MILLISECONDS); 191 } 192 193 /** 194 * Returns a string representation of the current elapsed time. 195 */ 196 @GwtIncompatible("String.format()") 197 @Override public String toString() { 198 return toString(4); 199 } 200 201 /** 202 * Returns a string representation of the current elapsed time, choosing an 203 * appropriate unit and using the specified number of significant figures. 204 * For example, at the instant when {@code elapsed(NANOSECONDS)} would 205 * return {1234567}, {@code toString(4)} returns {@code "1.235 ms"}. 206 * 207 * @deprecated Use {@link #toString()} instead. This method is scheduled 208 * to be removed in Guava release 15.0. 209 */ 210 @Deprecated 211 @GwtIncompatible("String.format()") 212 public String toString(int significantDigits) { 213 long nanos = elapsedNanos(); 214 215 TimeUnit unit = chooseUnit(nanos); 216 double value = (double) nanos / NANOSECONDS.convert(1, unit); 217 218 // Too bad this functionality is not exposed as a regular method call 219 return String.format("%." + significantDigits + "g %s", 220 value, abbreviate(unit)); 221 } 222 223 private static TimeUnit chooseUnit(long nanos) { 224 if (SECONDS.convert(nanos, NANOSECONDS) > 0) { 225 return SECONDS; 226 } 227 if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) { 228 return MILLISECONDS; 229 } 230 if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) { 231 return MICROSECONDS; 232 } 233 return NANOSECONDS; 234 } 235 236 private static String abbreviate(TimeUnit unit) { 237 switch (unit) { 238 case NANOSECONDS: 239 return "ns"; 240 case MICROSECONDS: 241 return "\u03bcs"; // 渭s 242 case MILLISECONDS: 243 return "ms"; 244 case SECONDS: 245 return "s"; 246 default: 247 throw new AssertionError(); 248 } 249 } 250 }