咱們能夠使用以下代碼進行程序好使計算和性能調試:java
Stopwatch stopwatch = Stopwatch.createStarted(); doSomething(); stopwatch.stop(); // optional long millis = stopwatch.elapsed(MILLISECONDS); log.info("time: " + stopwatch); // formatted string like "12.3 ms"
接下來咱們經過解讀其源碼來進行理解:ide
public final class Stopwatch { private final Ticker ticker;//計時器,用於獲取當前時間 private boolean isRunning;//計時器是否運行中的狀態標記 private long elapsedNanos;//用於標記從計時器開啓到調用統計的方法時過去的時間 private long startTick;//計時器開啓的時刻時間 }
經過對elapsedNanos、startTick結合當前時刻時間,能夠計算出咱們所須要的程序運行流逝的時間長度。工具
首先來看Ticker工具類:性能
public static Stopwatch createStarted() { return new Stopwatch().start(); } Stopwatch() { this.ticker = Ticker.systemTicker(); } private static final Ticker SYSTEM_TICKER = new Ticker() { @Override public long read() { //ticker工具類read方法,直接獲取機器的 納秒 時間 return Platform.systemNanoTime(); } }; static long systemNanoTime() { return System.nanoTime(); }
StopWatch的幾個關鍵方法:this
public Stopwatch start() { checkState(!isRunning, "This stopwatch is already running."); isRunning = true; startTick = ticker.read();//設置startTick時間爲stopwatch開始啓動的時刻時間 return this; }
public Stopwatch stop() { long tick = ticker.read(); checkState(isRunning, "This stopwatch is already stopped."); isRunning = false; //設置elapsedNanos時間爲方法調用時間-stopwatch開啓時間+上次程序stopwatch的elapsedNanos歷史時間 elapsedNanos += tick - startTick; return this; }
public long elapsed(TimeUnit desiredUnit) { return desiredUnit.convert(elapsedNanos(), NANOSECONDS); } private long elapsedNanos() { //若是stopwatch仍在運行中,返回當前時刻時間-stopwatch開啓時刻時間+歷史elapsedNanos時間(elapsedNanos只在stop和reset時會更新) //若是stopwatch已中止運行,則直接返回elapsedNanos,詳見stop() return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos; }
Stopwatch stopwatch = Stopwatch.createStarted(); doSomething(); stopwatch.stop(); // optional long millis = stopwatch.elapsed(MILLISECONDS); log.info("time: " + stopwatch); // formatted string like "12.3 ms"
使用stopwatch對程序運行時間進行調試,首先調用StopWatch.createStarted()建立並啓動一個stopwatch實例,調用stopwatch.stop()中止計時,此時會更新stopwatch的elapsedNanos時間,爲stopwatch開始啓動到結束計時的時間,再次調用stopwatch.elapsed(),獲取stopwatch在start-stop時間段,時間流逝的長度。spa
Stopwatch stopwatch = Stopwatch.createStarted(); doSomething(); //stopwatch.stop(); long millis = stopwatch.elapsed(MILLISECONDS); log.info("time: " + stopwatch); // formatted string like "12.3 ms"
createStarted啓動了一個stopwatch實例,stopwatch的時間持續流逝,調用elapsed方法,返回isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos;,此時獲得的返回值是當前時間和stopwatch.start()時刻時間的時間差值,因此是一個持續遞增的時間。pwa
若是須要在程序中對關鍵步驟的每一步進行進行持續度量,須要使用以下調用方式調試
Stopwatch stopwatch = Stopwatch.createStarted(); doSomething(); stopwatch.stop(); long millis = stopwatch.elapsed(MILLISECONDS); log.info("time: " + stopwatch); // formatted string like "12.3 ms" stopwatch.reset().start(); doSomething(); stopwatch.stop(); long millis = stopwatch.elapsed(MILLISECONDS); log.info("time: " + stopwatch); // formatted string like "12.3 ms"