年始のあいさつ
明けましておめでとうございます。本年も宜しくお願いします。
コードの出所
% git clone http://tddjs.com/code/04-test-to-learn.git
雛形作成
% mkdir Practice-JsBench/ % cd Practice-JsBench
HTML作成
% mkdir root % vi root/benchmark.html
<!DOCTYPE html> <html> <head> <title>Benchmark test</title> </head> <body> <script src="/js/mylibs/mybench.js"></script> <script src="/js/mylibs/benchmark_loops.js"></script> </body> </html>
ベンチ用関数を用意
% mkdir -p root/js/mylibs/ % vi root/js/mylibs/mybench.js
var benchmark = (function () { var times = {}; function init(name) { var heading = document.createElement("h2"); heading.innerHTML = name; document.body.appendChild(heading); var ol = document.createElement("ol"); document.body.appendChild(ol); return ol; } function runTests(tests, view, iterations) { for (var label in tests) { if (!tests.hasOwnProperty(label) || typeof tests[label] != "function") { continue; } (function (name, test) { setTimeout(function () { var start = new Date().getTime(); var l = iterations; while (l--) { test(); } var total = new Date().getTime() - start; times[name] = total; var li = document.createElement("li"); li.innerHTML = name + ": " + total + "ms (total), " + (total / iterations) + "ms (avg)"; view.appendChild(li); }, 15); }(label, tests[label])); } } function highlightExtremes(view) { // タイムアウトはほかのすべてのタイマーのあとにキューイングされる // すべてのテストが実行を週虜うし、 // timesオブジェクトに値がセットされているが保証される setTimeout(function () { var min = new Date().getTime(); var max = 0; var fastest, slowest; for (var label in times) { if (!times.hasOwnProperty(label)) { continue; } if (times[label] < min) { min = times[label]; fastest = label; } if (times[label] > max) { max = times[label]; slowest = label; } } var lis = view.getElementsByTagName("li"); var fastRegexp = new RegExp("^" + fastest + ":"); var slowRegexp = new RegExp("^" + slowest + ":"); for (var i = 0, l = lis.length; i < l; i++) { if (slowRegexp.test(lis[i].innerHTML)) { lis[i].style.color = "#c00"; } if (fastRegexp.test(lis[i].innerHTML)) { lis[i].style.color = "#0c0"; } } }, 15); } function benchmark(name, tests, iterations) { iterations = iterations || 1000; var view = init(name); runTests(tests, view, iterations); highlightExtremes(view); } return benchmark; }());
計測対象となるスクリプトを用意
% vi root/js/mylibs/benchmark_loop.js
var loopLength = 100000; // ループ実行のために配列をセット var array = []; for (var i = 0; i < loopLength; i++) { array[i] = "item" + i; } benchmark("Loop performance", { "for-loop": function () { for (var i = 0, item; i < array.length; i++) { item = array[i]; } }, "for-loop, cached length": function () { for (var i = 0, l = array.length, item; i < l; i++) { item = array[i]; } } }, 1000);
pspiを用意
% vi static.psgi
use Plack::Builder; builder { enable "Plack::Middleware::Static", path => sub { s!(.*/$)!${1}/index.html! }, root => './root/'; };
実行
% plackup static.psgi
感想
Test-Driven JavaScript Development 翻訳されてます。