2007年07月06日
JavaScript::SpiderMonkeyを試してみた
先週末くらいから、今さらかもしれませんがJavaScriptにはまっています。
Ajaxとかじゃなくて、割と純JavaScriptなんですけど、いやあ結構おもしろいですね。
まだ恥ずかしながらプロトタイプベースのオブジェクト指向とか十分に理解しているわけじゃないんですけど、ぼちぼちいろいろ試しています。
今メインでやっているのが、色んな地図サイトななんかで同じ位置情報を表すURL間の相互変換です。
各サイト間の変換情報をハッシュテーブルで持つ際に、どうしても一部クロージャでロジックそのものをテーブルに持たざるを得ない状況です。
で、同じ処理をサーバサイドでもやる必要が生じたんですが(Mappletとかグリモンとか、携帯サイトとか、いろんな形で同じ機能を提供するため)、変換テーブルをJavaScript用とPerl用の2つ持って両方メンテナンスするというのはいかにも面倒くさい。
そこで、その部分だけJavaScriptで処理したったらええんちゃう?と思って、SpiderMonkeyとJavaScript::SpiderMonkeyモジュールを導入してみました。
インストールは超簡単。
こちらの記事で取り上げられている通りにするだけで、手順的にも時間的にも簡単にできました。
大体この手の導入って、過去の経験上、導入記事に簡単に書かれていても一悶着二悶着あるものと身構えていたのですが、本当にあっさりと。
ただうちの場合、CVSは使ってないのでtarballをこちらから落としてきたことくらい。
テストも問題なく通り、拍子抜けするくらいでした。
ただ、「その部分だけJavaScript処理」といっても、他言語の処理環境を走らせるわけだし、処理が重くなる度合いが度を越えていたら使えないので、ちょっと実験してみました。
JavaScript::SpiderMonkeyでの処理を含んだFastCGIスクリプトを実行した際と、同じ処理をPerlにやらせた際の処理速度の比較。
試したのは、
- FastCGIループの外でJavaScript::SpiderMonkeyのオブジェクトを作って、JavaScript実行
- アクセスの都度JavaScript::SpiderMonkeyのオブジェクトを作って、JavaScript実行
- Perlでeval実行
- Perlでハードコーディングしての実行
んで、PerlとJavaScriptで、同じ内容で同じ処理をするプログラムとして、n9dさんのFizzBuzzコードを少々改題したものを使いました。
コード的にはこんな感じ。
#!/usr/bin/perl
use CGI::Fast;
use JavaScript::SpiderMonkey;
my $js = JavaScript::SpiderMonkey->new();
my $code = 'for($i=1;$i<=100;$i++){print_to_perl($i%15?$i%5?$i%3?$i:"Fizz":"Buzz":"FizzBuzz");}';
while (my $q = CGI::Fast->new) {
print "Content-type:text/html\n\n";
my $p = $q->param("mode");
if($p !~ /[0-3]/) {
print "Error!";
next;
}
if ($p < 2) {
my $ljs = $p ? JavaScript::SpiderMonkey->new() : $js;
$ljs->init();
$ljs->function_set("print_to_perl", sub { print "@_<br/>"; });
$ljs->eval($code);
$ljs->destroy() if ($p == 1);
} elsif ($p == 2) {
eval($code);
} else {
for($i=1;$i<=100;$i++){print_to_perl($i%15?$i%5?$i%3?$i:"Fizz":"Buzz":"FizzBuzz");}
}
}
sub print_to_perl { print "@_<br/>"; }
これでApacheBenchで1000回アクセスして実験してやると、こんな感じになりました。
|
SpiderMonkey (使い回し) |
SpiderMonkey (都度生成) |
Perl eval |
Perl | |
|
平均処理速度 [ms] |
22.030 | 28.222 | 5.860 | 5.076 |
|
秒あたり 処理回数 |
45.39 | 35.43 | 170.64 | 196.99 |
うーん、やっぱり歴然とした差がありますねえ…。
秒あたり1アクセスとかみたいに死ぬほど遅いってわけでもないですが、せっかくFastCGIで動かしてるのがCGI並みの処理能力になってしまう...。
かといって、やっぱ変換テーブル2重持ちの管理コストも結構なもんだし...。
死ぬほど遅かったりしたらすっぱりあきらめられるところなんですが、微妙な線だけに悩めるところです。
レイアウトが崩れてますよ
Posted by: at 2007年07月07日 00:06> こちらの記事で取り上げられている通りにするだけで、手順的にも時間的にも簡単にできました。
そちらの記事、チェックアウトする際にタグを何も指定していないので trunk (CVS HEAD) を取り出しているものと思われます。
今は Firefox 3/JavaScript 1.8 に向けての開発期間なので、JavaScript 1.8 での新機能(のうちの、既に実装されたもの)を試したいとか、開発版の追っかけをしたいというような目的であれば良いのです…
が、それは最新の開発版なので、たまにバグっていることもありますし、パフォーマンスも開発に伴って一定していませんので、特に速度比較とかをするのであれば、比較的安定していそうなバージョンを指定して取り出したほうが安心だと思います。
http://www.mozilla.org/js/spidermonkey/release-notes/
によると、リリース版としての最新は "JS 1.6.0 is based on the FIREFOX_1_5_0_9_RELEASE CVS tag" とのことなので、チェックアウトの際に -r FIREFOX_1_5_0_9_RELEASE と指定するのが、おそらく今の時点で最も安心できるバージョンでしょう。
ただ、それは Firefox 1.5.0.9 に内蔵されているのと同じもので、今となってはちょっと古いので、それより新しいものがよければ -r FIREFOX_2_0_0_4_RELEASE としてみるのもいいかもしれません。これは、JavaScript 1.7 系です。
> レイアウトが崩れてますよ
IE6 で見ると、盛大に崩れてますねぇ。
真ん中の column の中(の pre 要素の中)に長い行があるため、おそらく中身に合わせて勝手に広がる IE のバグのせいで column が勝手に広がってるんだと思います。
まともな layout engine に対しては、pre 要素を overflow: auto; にする等して、本来の幅の中に納まるようにするようにするところなんですが、IE に対してはどうやって回避したらいいんだろう…
![[ここギコ!]](http://kokogiko.net/logo.png)



・「定義できない」とのたまうものを自説根拠の説明の中で延々と使う不誠実(笑)(むにゅう!)
・絵文字標準化でのキャリア批判に思うこと(kokogiko)
・文化は変わっていくのは当たり前だからこそ、今問われているのはリアルタイムの選択(むにゅう!)
・絵文字標準化でのキャリア批判に思うこと(ひゅ〜)
・絵文字標準化でのキャリア批判に思うこと(kokogiko)
・文化は変わっていくのは当たり前だからこそ、今問われているのはリアルタイムの選択(kokogiko)
・文化は変わっていくのは当たり前だからこそ、今問われているのはリアルタイムの選択(むにゅう!)
・文化は変わっていくのは当たり前だからこそ、今問われているのはリアルタイムの選択(むにゅう!)
・文化は変わっていくのは当たり前だからこそ、今問われているのはリアルタイムの選択(むにゅう!)