なんとなく遅いと思っているgetElementById()だけど、「なんとなく」はよくないな…と思って計ってみる。
テストコード
この日記をローカルに保存して、テストコードを埋め込んだ。
しかし、どう見ても差がつきそうな気が…
<script type="text/javascript"> function no_cache() { var tab_name_list = new Array(); var tag_name = null; for(var i = 0; i < 10000; i++) { tag_name = document.getElementById('targer_element').tagName; tab_name_list.push(tag_name); } } var elements = {}; function cached() { var tab_name_list = new Array(); var tag_name = null; elements['targer_element'] = document.getElementById('targer_element'); for(var i = 0; i < 10000; i++) { tag_name = elements['targer_element'].tagName; tab_name_list.push(tag_name); } } </script> (中略) <input type="button" value="キャッシュなし" onclick="Profiler.profile('no cache', no_cache);"> <input type="button" value="キャッシュあり" onclick="Profiler.profile('cached', cached);"> <input type="button" value="レポート" onclick="Profiler.report();">
結果
テストはIE6で実施。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Microsoft Internet Explorer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
name: no cache
count: 5
duration: 1809.6 [ms]
-
- -
name: cached
count: 5
duration: 90.4 [ms]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
OK
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
まあ、そりゃあ差は出るよね…
ただ、相対的には遅いけど、絶対的な速度で問題になるかはよくわからないなぁ。
Profiler
Profilerはこんな感じ。
「Ajaxイン・アクション」を参考にするつもりだったけど、サンプルコードがあまりにコードが酷すぎたので自作。
Profiler = new Object(); Profiler.watches = new Object(); Profiler.start = function(name) { var watch = Profiler.watches[name]; if (!watch) { watch = new Array(); watch.avg = function() { var sum = 0; for(var i = 0; i < watch.length; i++) { sum += watch[i]; } return (sum / watch.length); } Profiler.watches[name] = watch; } var start = new Date(); return function() { var stop = new Date(); var duration = stop - start; watch.push(duration); }; } Profiler.profile = function(name, transaction) { var stop = Profiler.start(name); transaction(); stop(); } Profiler.report = function() { var name = null; var watch = null; var report = new Array(); for(name in Profiler.watches) { watch = Profiler.watches[name]; report.push('---'); report.push('name: ' + name); report.push('count: ' + watch.length); report.push('duration: ' + watch.avg()+ ' [ms]'); } alert(report.join('\n')); Profiler.watches = new Object(); }