jsPerf とは

JavaScript のコードスニペットに対してベンチマークを計測するサービスです。

一般的に、コードの速度を計測する際は console.time, console.timeEnd を使う事が多いと思いますが、 実行するたびに結果がブレたり、短い処理では正確な比較ができなかったりします。

jsPerf では何度か同じ処理を実行して最終的に一秒間に何回実行できたかをスコアにするので、実行時間が 1ms より小さい処理でも計測できたり、ブレがあっても大体のスコアが分かったりします。 このスコアを計算する部分は Benchmark.js というライブラリで書かれていますので、サーバサイドの JavaScript コードの速度を計測する際にも利用できます。

どういう時に使うのか

JavaScript では全く同じ事をするのに複数の手段があるということがよくあります。 例えば、Array オブジェクトで数値を先頭から順に書き込んでいくとき、Indexer を使って代入する方法と push メソッドを使う方法があります。

こういった際に、テスト用の HTML + JavaScript を作ってポチポチとリロードして各ブラウザで実行した結果をメモ帳にまとめていっても良いのですが、 jsPerf では比較したい部分のコードを書くだけで簡単に比較することができます。

上記の例のベンチマーク

使用上の注意

コードスニペットの正当性はチェックしてくれないので、各コードスニペットが同じ結果を返すのかなどは予めチェックしておく必要があります。 以前出回った i++, ++i の速度比較など、 不公平な条件での結果をスコアだけみて「こっちの方がはやい!」などと思わないようにしましょう。 あまりに直感と掛け離れた結果は自分でいじってみるなど、疑ったり、理由を考える事も大切です。 ちなみに、上記の例ではベンチマーク対象データの生成を setup でやっておけば問題ありません。

JSPerfViewとは

jsPerf を使いだすと、ベンチマーク結果の共有を行いたい事が多々あります。
JSPerfView は HTML5 Rocks の canvas パフォーマンスチューニングのページで利用されている、jsPerf の計測結果をページに埋め込むためのものです。 上で表示されているグラフは JSPerfView を使って表示されています。 iframe を使って埋め込みます。 jsPerf の出力結果とは異なり、スニペットごとに各ブラウザの結果をまとめて表示します。(jsPerfでは各ブラウザごとにスニペットの結果をまとめて表示する)

簡単な使い方

プロジェクトページから何でも良いのでダウンロードしてきて、そのまま丸ごとどこか見れる場所にアップロードします。
自分は GitHub で fork してそのまま qh-pages ブランチに push して利用しています。

ベンチマーク結果を埋め込みたい場所で、以下のように iframe 要素に embed.html を表示したい jsPerf ベンチマークの Browserscope test ID 付きで指定する。

<iframe src="http://imaya.github.com/jsperfview/embed.html?id=agt1YS1wcm9maWxlcnINCxIEVGVzdBiPnYkODA"></iframe>

Browserscope test ID の確認方法

対象となる jsPerf のページを開き、計測結果のグラフの上の方にある "Browserscope" というリンクがあるので、これの URL の末尾が Browserscope test ID です。 例えば、以下の URL の強調した部分です。

http://www.browserscope.org/user/tests/table/agt1YS1wcm9maWxlcnINCxIEVGVzdBiPnYkODA
jsperf-browserscope-ss

バグとか表示方法の変更とか

グラフの表示がおかしくなる

現在、重い処理や貧弱なスマートフォンなどで実行して Ops/sec が 1 未満の結果を含む際にグラフがずれるようです。 この現象への対処は以下の変更を行う事で可能です。

diff --git a/js/chart.js b/js/chart.js
index e778b45..0281d4f 100644
--- a/js/chart.js
+++ b/js/chart.js
@@ -60,7 +60,7 @@ function parseChart_(response) {
       }
       // Compute series data
       var result = parseInt(platformResults[testName].result, 10);
-      if (result && !isNaN(result)) {
+      if (typeof result === 'number' && !isNaN(result)) {
         data.push(result);
       }
     }

全てのブラウザでの結果を表示したい

デフォルトのままでは、jsPerf でテストを行ったブラウザでも結果が表示されないものがあります。 これは、Browserscope の API でデータを取得する際にパラメータを省略すると "Top Browsers" のしか結果を返さないようになっているためです。 詳しくは Browserscope の API ページを参照してください。 全ての結果を表示するには以下のように変更します。

diff --git a/js/chart.js b/js/chart.js
index 2aa93f6..f682877 100644
--- a/js/chart.js
+++ b/js/chart.js
@@ -12,7 +12,7 @@ function Chart(testId) {
   this.chart = null;
 }
 
-Chart.URL_FORMAT = 'http://www.browserscope.org/user/tests/table/{ID}?o=json&callback=?';
+Chart.URL_FORMAT = 'http://www.browserscope.org/user/tests/table/{ID}?v=3&o=json&callback=?';
 Chart.MODERN = /Firefox ([4-9]|[1-2][0-9])|Chrome [1-2][0-9]|IE 9|IE 1[0-9]|Safari ([5-9]|1[0-9])/;
 Chart.MOBILE = /iPhone|iPad|Android/
 

グラフのサイズを変更したい

グラフが大きすぎる場合などサイズを変更したいことがあります。そういう場合は以下のように Highchart のオプションを指定してやれば変更できます。
ちなみに、iframe の height はこのグラフの大きさ + 40px くらいで指定するとちょうど良くなる事が多いようです。

diff --git a/js/chart.js b/js/chart.js
index b967797..6859bb8 100644
--- a/js/chart.js
+++ b/js/chart.js
@@ -87,7 +87,8 @@ function parseChart_(response) {
 function renderChart_(chartInfo, id, type) {
   chartInfo.chart = {
     renderTo: id,
-    type: type
+    type: type,
+    height: 300
   };
   chartInfo.yAxis = {
     title: {