オルタナティブ・ブログ > 少しでもパラノイアになってみる >

知的好奇心を満たすために、いろいろなことにチャレンジする

太陽系のN-bodyシミュレーションJavascriptベンチを作ってみた

»

The Computer Language Benchmarks Gameに各種言語毎のベンチ結果が掲載されています。Javascriptも結構速いんだよ的データがもありますが、私が一番興味を引いたのはJavascriptでN-bodyシミュレーションがあるところです(N-Bodyが何かは検索してみてください)。

ただし、このソースはコンソールで動くようになっているため、ブラウザ上では動きません。これをブラウザ上に移植してみました。

単にブラウザだけで動くようにするには面白みがまったくないため、以下の機能を盛り込みました。

・SVGで移動しているところを見れるようにする
・データは太陽と木星以降の惑星だが、水星、金星、地球、火星も加えた(冥王星は加えなかった)

ただし、以下の改悪もしています。

・Z軸は計算しないことにした
・水星などの初期値の位置と速度が分からなかったので、一律太陽から右側に一列に並べた(wikippediaに太陽からの距離、速度がある)
・エネルギーを求めていない(求めて表示しても、"でっ?"となるため)

物理出身にあるまじき改悪かも知れませんが、天体とか宇宙出身でないので、勘弁してください。

星と色は以下のとおりです。

Sun->red
Mercury->cyan
Venus->yellow
Earth->blue
Mars->magenta
Jupiter->lime
Saturn->darkslategray
Uranus->gray
Neptune->black

重なることを考慮したため、水星~火星の星のサイズはすごく小さいです。SVGで作っているため、拡大しても汚くはなりません。"Ctrl"+"+"でサイズを大きくしてください。また、元に戻すときは"Ctrl"+"0"で一気に戻ります。

以下のYearを指定してStartボタンを押してください。惑星がぐるぐる回ります。ただし、ある事情によりIE 9は動きません(後述)。当然IE 8以前はSVGをサポートしていないので、動くこともありえません。

Year:

time(ms):

Year:10,000で、各ブラウザのベンチ結果は以下のとおりです。使用したPCは、ThinkPad X201s(Core i7 L620(2.0GHz))、メモリ4GB、Windows 7 64bitです(いつもと違うのは帰省しているからです)。

Opera 11.10:10,2498(ms)
IE 9:33,772(ms)
Chrome 11.0:40,053(ms)
Firefox 4.0:100,665(ms)
Safari 5.0:102,498(ms)

たった9個の恒星・惑星の重量の計算とSVGの描画ぐらいの負荷です。個体数が少なすぎるため、重力の計算量は軽いものになっています。

ここでOpera速い!となるかというと、そう簡単ではありません。

SVGの描画を行うために、このベンチは位置決めの計算→SVG変更後にsetTimeoutで一度スリープ(ただし、そのタイムは1msです)しています。連続だとSVGの位置を変更しても更新されません。ですが、ブラウザのsetTimeoutの誤差はひどいことで有名です。

ここで、setTimeoutの精度に関するベンチマークを作ってみました。waittimeを変更して、Startボタンを押してください。


waittime:(ms)
loop:

結果は、以下になっています。

wait timeをある値に設定したときの平均的なスリープ時間です(new Date()の間にif、加算とsetTimeoutの3行が入っていますが、影響度を見る限りは小さそうです)。標準偏差を取り2σ分誤差としています。

この結果を見る限りは、Operaの優秀性が突出していることになります。そうです、私が作成した太陽系N-Bodyシミュレーションベンチは、setTimeoutベンチだったのです(私はsetTimeoutの方がsetIntervalよりも好き)。あまり多くない個体数のN-Bodyシミュレーションはベンチとしては軽すぎました(計算もSVGの描画も)。個体数が多くなればまた違ったものになるでしょうし、応用すれば太陽系ではなく、ランダムな固体で行うともっと面白いかも知れません(その場合は、衝突も考慮に入れる必要がありますが)。

現時点ではブラウザのタイマー系は10ms未満は動作に差がありすぎます。10ms未満を指定しないほうが良さそうと言う話は以前から聞いていましたが、結果を見ると本当に理解できました。早く追いついてFirefox/Safari。HTML5が普及すれば、Javascriptでもゲームをする時代が来ると思いますので、タイマー系ももう少し対応できるといいですね。ついにで、掲載していませんが、setIntervalの精度はsetTimeoutとほとんど同じでした(普通に考えて、同じつくりだよね)。

太陽系N-bodyシミュレーションは、軌道のデータを入れているわけではありません。初期状態で設定しているのは、位置、速度、質量だけです。にも関わらず、正確ではありませんが、太陽系の惑星っぽい動き(楕円系)を見せてくれます。いや、シミュレーションって偉大ですね。

ついでに、IE 9がこのブログに貼ってあるスクリプトが動かない理由は、DOCTYPEにSVGの記載がないためです。以下のようにすれば動きます。

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

ここではお借りしている環境ですので、DOCTYPEを変更することは出来ません。そこで、HTMLをソース置き場のn-body_solarsyste_r4.htmlに配置しましたので、IE 9で試してみたい場合はそれで実行してみてください。また、setTimeoutベンチも付いています。興味があれば使ってください。

Comment(0)