Benchmark.js のサンプル アプリでは、パフォーマンス テストを JavaScript 関数ではなく文字列として定義しています。
https://github.com/bestiejs/benchmark.js/blob/master/example/jsperf/index.html#L250
このようにパフォーマンス テストを定義する利点はありますか? なぜそれはただの機能ではないのですか?
Benchmark.js のサンプル アプリでは、パフォーマンス テストを JavaScript 関数ではなく文字列として定義しています。
https://github.com/bestiejs/benchmark.js/blob/master/example/jsperf/index.html#L250
このようにパフォーマンス テストを定義する利点はありますか? なぜそれはただの機能ではないのですか?
私が知る限り、長い一連の呼び出しを通じて、そこにある関数コードはgetSource という名前のbenchmark.js の関数になり、とにかくそれを文字列に変換します。
/**
* Gets the source code of a function.
*
* @private
* @param {Function} fn The function.
* @param {String} altSource A string used when a function's source code is unretrievable.
* @returns {String} The function's source code.
*/
function getSource(fn, altSource) {
var result = altSource;
if (isStringable(fn)) {
result = String(fn);
} else if (support.decompilation) {
// escape the `{` for Firefox 1
result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1];
}
// trim string
result = (result || '').replace(/^\s+|\s+$/g, '');
// detect strings containing only the "use strict" directive
return /^(?:\/\*+[\w|\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result)
? ''
: result;
}
これは関数 "clock" 内で行われます。これは、clock が呼び出されるたびに文字列からベンチマーク関数を作成する動機について、別の説明を提供します。
// Compile in setup/teardown functions and the test loop.
// Create a new compiled test, instead of using the cached `bench.compiled`,
// to avoid potential engine optimizations enabled over the life of the test.
私はbenchmark.jsの専門家ではありませんが、ライブラリが故意に未加工のコードからベンチマークを開始しようとしており、これまでに見たことのないコードでコンパイラ/インタープリタを強制的に実行させようとしているようです。コードを最適化するためにロード時に 5 秒間フリーズする架空のブラウザーは驚くべきパフォーマンスを発揮する可能性がありますが、ベンチマークでコンパイルに費やした 5 秒間を無視するのは公平ではありません。また、スコープと例外処理を制御するために、元のコードにかなりの変更を加えています。ベンチマークは、コードを適切に操作するためにコードを文字列として必要とするだけです。
この見方では、関数を文字列として渡すことが特に重要というわけではありませんが、そうしない理由はありません。いずれにせよ文字列として終わることになるからです。
この場合、関数を文字列または参照として追加しても、パフォーマンスのテストには影響しません。
このbenchmark.js#L336と以下のサンプルを見てください。ドキュメントは、それはあなた次第だと言っています。
関数を見たいと思うかもしれませんclock
:benchmark.js#L2452。関数が参照として渡されると、文字列に変換されることがわかります。さらに、テスト全体が文字列として作成されます。
なぜそれがより良い解決策なのか、すべての利点を私は知りませんが、これらは私の頭に浮かびます:
私が指摘したすべての利点は、コードを実行する技術的な側面とは何の関係もないことに注意してください。文字列の場合は、定義された回数だけ解釈して実行する必要があります。次に、経過時間がチェックされ、それがベンチマークの結果です (基本的に)。全体のコンセプトは同じです。
var counter = N,
after,
before = performance.now;
while(counter--) {
myFun();
}
after = performance.now;
console.log(after - before);