JavaScriptで処理時間を計測する本当に正しい方法

どの処理にどれだけ時間がかかっているのか・・・調べたいことってありますよね?

でも正しい計測方法を知っていないと精度が悪かったり余計な手間がかかってしまうかもしれません。

ということでJavaScriptでの本当に正しい処理時間の計測方法について紹介します。

Date.nowは時間計測に使ってはダメ!

JavaScriptには現在の時間をミリ秒で返してくれるDate.now関数が用意されています。

しかし、処理時間を計測するのにこの  Date.now  は使うべきではありません。

 

確かにこの関数を使えば次のように簡単に時間が計測できます。

これは以外とよく使ってしまう方法ではないでしょうか。

僕自身もこういうやり方で時間を測っていたことがありました。

 

ですが  Date.now  を使うのは次のような点であまりいいことではありません。

  • ミリ秒以下の精度で計測できない
  • そもそも計測用の関数でない

精度がそもそもミリ秒までなのでそれ以下の精度で計測ができないというのが問題です。

じゃあ代わりに何を使えばいいのかというのが次で説明する本題です。

処理時間の計測には performance.now を使おう

処理時間を測るのに一番適しているのはperformanceインターフェースを使うことです。

これはパフォーマンス計測のためだけに用意された専用のAPIです。

 

そして現在の時間を取得するのに  performance.now  が使えます。

使い方は  Date.now  全く同じです。

 

この関数で返される時間の単位はミリ秒です。

しかし次のようにミリ秒の小数点以下まで表示されるのが  Date.now  との違い

小数点以下がどの桁まで表示されるかはブラウザ次第です。

ですが間違いなくミリ秒以下の精度で時間を計測することが可能になります。

 

なのでこれを使うことで制度の高い計測が可能です。

例えば次が  performance.now  を使った計測のコード例

これを実行してみるとコンソールには次のようにミリ秒以下までしっかり表示されます。

ただこれだと余計な桁まで表示されてしまうので少し見にくいです。

 

なので実際は次のようにミリ秒以下3桁くらいで丸めればいいと思います。

toFixed関数が指定した小数点以下の桁数で丸めるための関数です。

これで表示する時に3桁固定になります。

以上が performance.now で時間計測する方法です。

performaceで時間計測をさらに便利にするには

performaceインターフェースでは時間を計測するのに便利な方法もあります。

それがmeasure関数mark関数の2つを組み合わせるやり方です。

 

手順は大まかに書くと次の通り

  • mark関数で計測開始地点にマーキング
  • mark関数で計測終了地点にマーキング
  • measure関数で開始から終了地点まで計測
  • getEntriesByName関数で計測時間取得

開始地点と終了地点にマーキングしてmeasure関数で後から計測するという方法です。

 

この説明だと分かりにくいと思うので具体的な例を出しましょう。

それが次のmark関数とmeasure関数を使った時間計測のコード例

一番最後当たりの  getEntriesByName  で計測名に結び付けられた複数の結果を取得しています。

その1つ1つの結果の  duration  プロパティに計測時間が入っています。

 

この方法だと無駄な変数が増えずスマートに書けるがメリットですね。

また好きな場所で時間計測できるのでデバッグに役立ちそうです。

補足 : PHPで処理時間を測るには・・・

もしWeb開発でPHPも使う、という人はPHPでの計測方法も知っておくと役立ちます。

PHPの場合、次の2関数を使うことで処理時間計測が可能

  • time関数 : 処理時間を「秒」で計測
  • microtime関数 : 処理時間を「マイクロ秒」で計測

測り方はJavaScriptの時と同じく、最後から最初の時間を引くだけです。

 

ちなみに詳しいやり方とかコード例は次でまとめた通り

PHPとJSは併用することが多いので、両方の時間計測の仕方を知っておいて損はありません。

ここまでのまとめ

ということで簡単にここまでをまとめると次の通り

  • 時間計測にDate.nowは使うべきではない
    精度が低く計測用でもないので使いにくいから
  • 時間計測にはperformanceインターフェースを使う
    performance.now関数から現在の時間をミリ秒以下で取得可能
    またmark関数measure関数を組み合わせるやり方もあり

ということでJavaScirptでの時間計測についてまとめてみました。

処理のボトルネックを測るのにこれから使っていこうと思います。

ではでは($・・)/~~~

Shareこの記事をシェアしよう!

Commentsこの記事についたコメント

2件のコメント
  • KazutoAsano

    このサイトを見てferformance.nowを知りました。使ってみたらDate.nowと同じミリ秒の整数を返してくれて残念でなりません。ここに記入してあるような小数点以下が表示されてマイクロ秒の精度で時間が測定できるようにするにはどうしたらいいんでしょう。今、廊下で測る音の速さのスクリプトを作っています。

    10月 28, 2022 9:18 am
    • ぴー助

      コメントありがとうございます。
      実はかならずマイクロ秒精度とは限りません。

      ▼ performance.now() : 時間精度の引き下げ

      タイミング攻撃やフィンガープリンティングから保護するため、ブラウザーの設定によっては、 performance.now() の精度が丸められることがあります。 Firefox では、 privacy.reduceTimerPrecision の設定が既定で有効になっており、既定で 1 ミリ秒となっています。

      引用元 : https://developer.mozilla.org/ja/docs/Web/API/Performance/now

      上記のようにFireFoxでは精度が1ミリ秒に丸められるため、マイクロ秒精度では計測できないみたいです。ただしChromeでは間違いなくマイクロ秒精度で返ってくるので、Chromeでもミリ秒精度なら理由は分からないです。ブラウザの設定などが原因かもしれません、

      10月 28, 2022 9:43 pm

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください