もっと速くするために(トップレベルオブジェクトの省略)
昨日の続きです。
ブラウザで動作する JavaScript では、トップレベルオブジェクト(window)を省略できます。これにより、window.setTimeout や window.document と書くかわりに setTimeout や document と書いても動作します。
今日は、省略すると速くなるのか調べました。
window.userObject1 = 0; // プリミティブ型 window.userObject2 = []; // Array window.userObject3 = {}; // Hash // window.xxx でアクセス function job1(n) { for(var i = 0; i < n; ++i) { ++window.userObject1; window.userObject2.push(i); window.userObject3[i] = i; } } // alias(win = window) でアクセス function job2(n) { for(var i = 0, win = window; i < n; ++i) { ++win.userObject1; win.userObject2.push(i); win.userObject3[i] = i; } } // window を省略 function job3(n) { for(var i = 0; i < n; ++i) { ++userObject1; userObject2.push(i); userObject3[i] = i; } }
jobn を 10万回コール, n = 1
単位はms, IE6 と IE7 はそれぞれ別の PC で測定し、IE8 とその他のブラウザは同じ PC で測定しています。
job1 | job2 | job3 | |
IE 6.0 | 7719 | 7281 | 5125 |
IE 7.0 | 2917 | 2808 | 2044 |
IE 8.0 | 2453 | 2438 | 1375 |
Opera 9.64 | 750 | 469 | 265 |
Opera 10 | 437 | 344 | 250 |
Firefox 2.0 | 1031 | 1000 | 750 |
Firefox 3.0 | 988 | 789 | 174 |
Firefox 3.5 | 1027 | 809 | 208 |
Firefox 3.5(JIT) | 1024 | 822 | 201 |
Safari 4.0 | 118 | 126 | 49 |
Google Chrome 4β | 155 | 93 | 16 |
jobn を 1000回コール, n = 100
job1 | job2 | job3 | |
IE 6.0 | 5922 | 5734 | 3979 |
IE 7.0 | 2091 | 1965 | 1280 |
IE 8.0 | 2391 | 2344 | 1312 |
Opera 9.64 | 672 | 281 | 219 |
Opera 10 | 391 | 250 | 203 |
Firefox 2.0 | 719 | 656 | 422 |
Firefox 3.0 | 1016 | 642 | 136 |
Firefox 3.5 | 967 | 639 | 169 |
Firefox 3.5(JIT) | 966 | 635 | 163 |
Safari 4.0 | 126 | 134 | 57 |
Google Chrome 4β | 191 | 46 | 14 |
jobn を 1回コール, n = 10万
job1 | job2 | job3 | |
IE 6.0 | 6063 | 5968 | 3938 |
IE 7.0 | 2215 | 2153 | 1389 |
IE 8.0 | 2453 | 2422 | 1344 |
Opera 9.64 | 688 | 281 | 234 |
Opera 10 | 391 | 266 | 218 |
Firefox 2.0 | 890 | 750 | 547 |
Firefox 3.0 | 1118 | 722 | 221 |
Firefox 3.5 | 1080 | 712 | 226 |
Firefox 3.5(JIT) | 1086 | 732 | 232 |
Safari 4.0 | 252 | 212 | 141 |
Google Chrome 4β | 168 | 51 | 36 |
まとめ
- window を省略すると速くなります
- window オブジェクト直下の要素は、名前解決において特別な扱いを受けているようです
- 各ブラウザで足並みが揃っているので、最適化しやすく最適化の効果が高いポイントなのでしょうね
- window オブジェクト直下の要素は、名前解決において特別な扱いを受けているようです
- Firefox3.5(JIT ON) よりも Firefox2 のほうが体感的に速かった(CPU 負荷的にも)
- JIT ON/OFF で結果に差が見られませんでした。最適化の対象外なのかもしれませんね
- document のアクセスを高速化するには ⇒ amachang の 「一行で IE の JavaScript を高速化する方法」を掘り下げてみた - latest log
おまけ
window. userObject1 だけでテストした結果。
Firefox2 のスコアに注目です。
// window.xxx でアクセス function job1(n) { for(var i = 0; i < n; ++i) { ++window.userObject1; } } // alias でアクセス function job2(n) { for(var i = 0, win = window; i < n; ++i) { ++win.userObject1; } } // window を省略 function job3(n) { for(var i = 0; i < n; ++i) { ++userObject1; } }
jobn を 10万回コール, n = 1
job1 | job2 | job3 | |
IE 6.0 | 3359 | 3313 | 2297 |
IE 7.0 | 1092 | 1045 | 718 |
IE 8.0 | 1078 | 1094 | 563 |
Opera 9.64 | 250 | 266 | 93 |
Opera 10 | 156 | 156 | 94 |
Firefox 2.0 | 485 | 484 | 328 |
Firefox 3.0 | 470 | 475 | 95 |
Firefox 3.5(JIT) | 460 | 468 | 108 |
Safari 4.0 | 31 | 30 | 3 |
Google Chrome 4β | 75 | 81 | 2 |