Guava Stopwatch源碼解析

咱們能夠使用以下代碼進行程序好使計算和性能調試: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"
相關文章
相關標籤/搜索