昨日のベンチマーク・プログラムだが、MacやWindows上で走らせて60-70fps程度しか出ていない事に驚いた人も多いかも知れないのでひと言補足しておく。
あのベンチマーク・プログラムは1フレーム描画するごとにSetTimeout()を使って1msの遅延で関数updateFrameを呼び出し、実際に1秒間に何回呼び出されるかを測定している。スマート・フォン上でこのベンチマーク・プログラムを走らせると、フレームの描画の部分に30msとか40msとかが必要なので、その結果33fps、25fpsなどの測定結果が得られる。
ということは、Javascriptの実行速度が猛烈に早ければ1000fpsも可能なはずだが、どんなに高速なパソコンを使おうと、どんなに描画のロジックを単純化しようと、実測値が通常100fpsを超えることはないのをご存知だろうか。
マルチタスク・マルチウィンドウ・マルチタブ前提のパソコン用のブラウザーの場合、もしJavascriptを全力で実行してしまうと、このベンチマークのように最小の遅延でスクリプトを実行するページを開いたとたんにブラウザー自身のレスポンスが極端に悪くなってしまう。
そのために、たとえプログラマーがJavascript側でSetTimeout()の遅延パラメータとして1msを指定したとしても、最低でも10msとか15.6msの遅延後にしかタイマー関数を呼ばない、という設計になっているのが普通だ(IE, Safari, Firefox, Operaの場合。Google Chromeに関しては追記を参照)。
【追記】このエントリーを書いていて、Google Chromeに関する面白いディスカッションを見つけた(
参照)。初期の実装では、このシステム側で挿入する遅延を1msにしておいたところ、開くページによってはCPUを使い切ってしまうという問題が出たという話だ。最新のビルド(4.0.212.0 for MAC)を試したところ、ベンチマークの結果は70fps〜160fps(ページの開き方で結果が大きく変わる)でCPUを使い切ることはなかったので、何か他のブラウザーとは異なる遅延の仕組みを持っているようだ。
【追記2】ちなみに、「どうせシステム側が遅延を入れて来ると知っているならSetTimeout()に0msを渡せばいいのに」と思う人も多いと思うので(実際にそんなテクニックを使うJavascriptのフレームワークもある)説明しておくと、私としては「0msってことは遅延なしにすぐに呼び出してもいいのね」と誤解されたくないからである。実際Google Chromeの初期の実装はそれに近い問題を抱えていたわけで、その意味では「石橋を たたいて渡る 1ms(字余り)」である。
0msは「あたしゃ単にqueue代わりに使いたいだけなのよ」という宣言ですかね
Posted by: KTy | 2009.09.18 at 10:04
ご参考まで。
http://d.hatena.ne.jp/NyaRuRu/20080909/p1
Posted by: かめぞう | 2009.09.18 at 13:39