LoginSignup
0
0

More than 1 year has passed since last update.

TypeScript/JavaScript: performance.mark を使うときは初回 mark は捨てる?

Last updated at Posted at 2022-12-16

背景

ある Library 関数において無駄な処理だなぁと思った際に、感覚ではなく、客観的に見せる為に速度比較をしようとした。

TypeScript 初心者が辿り着いたのが

  1. performance.now による計測
  2. performance.mark/measure による計測

どちらも同じ performance なんで、何が変わるんだろうとなんも考えず計測関数を用意して測ってみたところ・・

何故か、想定通りに計測出来なかった。その原因推測と対処法の共有

そう
Solve「本質を追求し問題を解決する」
の実現・・の筈 :hamburger:

結論

  • performance.mark を使う際は、一個目は cache が効いてなさそうなので、使い捨てしよう。(たぶん

ほんとかどうかは、下層まで追ってない(追い方知らない)ので不明ですので、詳しい人の教えがあると嬉しい

調査内容

コード

計測関数

performance.now を使った計測関数
function measureExeFunc(executeFunction: { (timestamp: Date): number; (arg0: Date): void; }, date: Date) {
    var startTime = performance.now();
    executeFunction(date);
    var endTime = performance.now();
    console.log(`${executeFunction.name}: `, endTime - startTime);
}
performance.mark/measure を使った計測関数
function measureExeFunc2(executeFunction: { (timestamp: Date): number; (arg0: Date): void; }, date: Date) {
    performance.mark('ini'); // ここがcache 効かせるための捨て mark
    performance.mark('start');
    executeFunction(date);
    performance.mark('end');
    performance.measure(executeFunction.name, 'start', 'end');
    console.log(performance.getEntriesByType('measure'));
    performance.clearMarks();
    performance.clearMeasures();
}

被計測関数

単純にループ処理にしてみた

100 count
const functionMeasured100 = (timestamp: Date) => {
    let sum = 0;
    for (let count = 0; count < 100; count++) {
        sum += count;
    }
    return sum;
};
1000 count
const functionMeasured1000 = (timestamp: Date) => {
    let sum = 0;
    for (let count = 0; count < 1000; count++) {
        sum += count;
    }
    return sum;
}

実際の計測処理

参照キャッシュが影響しないように2つの Date() を用意して計測

const currentDate2 = new Date();
currentDate2.setMilliseconds(currentDate2.getMilliseconds() - 5);
const currentDate3 = new Date();
currentDate3.setMilliseconds(currentDate3.getMilliseconds() + 5);
measureExeFunc(functionMeasured100, currentDate2);
measureExeFunc(functionMeasured1000, currentDate3);

measureExeFunc2(functionMeasured100, currentDate2);
measureExeFunc2(functionMeasured1000, currentDate3);

計測結果

読み捨て無し

mark('ini') の部分をコメントアウトした場合
image.png

読み捨て追加

image.png

所感

mark() の初回に now を記録しつつ、初期化処理で時間がかかってそう

Documents

あとがき

VS Code でのインテリセンスもほんと便利ですね。
便利過ぎて、無いとコードかけそうにない気がします :laughing:

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