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"
相关文章
相关标签/搜索