0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

適当なストップウォッチなクラスを作った

Posted at

時間が測れます。以上。

type StopWatchLap = {
  type: 'start' | 'lap' | 'stop';
  date: Date;
  message: string;
};

export class StopWatch {
  private _laps: StopWatchLap[] = [];
  start(message: string = '') {
    this._laps.push({
      type: 'start',
      date: new Date(),
      message,
    });
  }
  pushLap(message: string = '') {
    this._laps.push({
      type: 'lap',
      date: new Date(),
      message,
    });
  }
  stop(message: string = '') {
    this._laps.push({
      type: 'stop',
      date: new Date(),
      message,
    });
  }
  reset() {
    this._laps.length = 0;
  }
  valueOf() {
    const startLap = this._laps.find(lap => lap.type === 'start');
    const stopLap = this._laps.find(lap => lap.type === 'stop');
    return startLap ? (stopLap?.date ?? new Date()).valueOf() - startLap.date.valueOf() : 0;
  }
  getLapDetails() {
    const startLap = this._laps.find(lap => lap.type === 'start');
    return this._laps.map((_, idx) => this.getLapInner(idx, startLap));
  }
  getLap(n: number) {
    const startLap = this._laps.find(lap => lap.type === 'start');
    return this.getLapInner(n, startLap);
  }
  private getLapInner(n: number, startLap: StopWatchLap | undefined) {
    const lap = this._laps[n];
    const prevLap = this._laps[n - 1];
    if (startLap) {
      const startTime = startLap.date.valueOf();
      return {
        ...lap,
        time: lap.date.valueOf() - startTime,
        lapTime: lap.date.valueOf() - (prevLap?.date.valueOf() ?? startTime),
      };
    } else {
      return {
        ...lap,
        time: 0,
        lapTime: 0,
      };
    }
  }
  get milliseconds() {
    return this.valueOf();
  }
  get seconds() {
    return this.valueOf() / 1000;
  }
  get isRunning() {
    return this._laps.some(lap => lap.type === 'start') && this._laps.every(lap => lap.type !== 'stop');
  }
}

計測中に実行するであろう start pushLap stop の実行コストを少なくすることを目標にしました。
値の取り出しは計測終了後に行うはずなので、コストは気にしていません。
さささーって書いたので正直テストとかしてません。まあでばっぐようだし

使い方

const stopwatch = new StopWatch();
stopwatch.start('計測開始');

await 時間のかかる処理();
stopwatch.pushLap('ラップ1');

await 時間のかかる処理();
stopwatch.pushLap('ラップ2');

await 時間のかかる処理();
stopwatch.pushLap('ラップ3');

stopwatch.stop('計測終了');

console.group(`ストップウォッチ実行ログ (${stopwatch.milliseconds}ms)`);
for (const lap of stopwatch.getLapDetails()) {
  console.log(`${lap.message}: ${lap.date.toISOString()}${lap.lapTime ? ` (${lap.lapTime}ms)` : ''}`)
}
console.groupEnd();
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?