rhinoとindy

rhinoのコンパイル・モードじゃなくてインタプリタ・モードにindy使えば速くならないかなぁ

rhino fork

Octane-v2.0のスコアが平均930くらいにまで到達した。一部で1010超えたりするけど平均すると930程度。

目標はindy使わずにスコア1000程度なのでもう少しで達成する(indyなしでスコア1000、indyありでさらに2倍出せればnashornと互角と考えている/ただしindyでスループットを上げるとレスポンスタイムは落ちると思う)。しかし、これを達成したら今度はindy使ってさらに高速化……を目指すわけではない。その前に元々遅いコードのrewriteをしなければいけない。今やってるのは古いコードを新しく書き換えるついでにチューニングしてるだけなので遅い部分は触れていない。というか高速化そのものが目的ではなく古いコードをモダンなコードに置き換えるのが目標なので高速化は後回し。遅いコードのrewriteよりツール類の刷新の方が優先度が高い。

しかもチューニングに関してはoriginalのrhinoよろしく経験則による手書きチューニングなので時間がかかる。ただoriginalにあったstr1 == "foo" || "foo".equals(str1)のような事はまだ手を出していないし、ソースコード上のフィールドの定義順意識して手動でアラインメントするとかガチガチなチューニングまだまだ余地があるのでやってみると面白いかと思っている。indyは別にそれ使えば早くなるわけでもないしindy固有のノウハウがいるしindy使ってディスパッチ・システム書くとどうしても巨大になりすぎるからやっててあまり面白くないしrutimeが十分小さいrhinoの特徴に反する。

しかも、Octane-v2.0を連続10回程度ならnashornとrhino forkとの差はコンパイラ・モードで2倍程度、インタプリタ・モードでもたったの12倍程度。さらに専用VM持っているブラウザのjavascript処理系とは到底張り合えないのでスループットにこだわるつもりはない。sun-spiderの速さなら元からrhinoの方が上でさらにruntimeが小さいっていうのはそれだけでもrhinoのセールスポイント。ツール全部入りでjarのサイズが1Mbyte程度の処理系なんて今どきないと思う。

なので最終的にはindyに移行するけどそれは今ではない。ただ、ディスパッチ時の呼び出し階層を減らしたりMethodHandleで使いやすいような設計にはしてindyコードとの親和性は考えていく。

むしろ、そこらよりrhinoの吐くバイトコードの質が悪いからjava用IDEでデバッガブルじゃないとかruntimeよりツール群のイマイチな質のほうが改善すべき点だと当初から考えているので早くそこに手を掛けたい。

es4の話

es4のTypeはself-hostingしないほうが良いと思うんだよね。

JavaVMだと型保証がしづらい。型チェックとかキャストとか。型パラメタがreifiable typeだったらよかったのに。

comb sort

いまArray.prototype.sortの再実装実験でcomb sortを実装しているんだけどさすがに速度はtim sortに負ける。でも、メモリを使わないかと思ったら一度jsのオブジェクトからjavaの配列へ変換してるせいで大して差がない。多分thisArgがNativeArrayかつdenseOnlyのとき内部配列を直接ソートする方法を取れば今より早くなると思うんだけどNOT_FOUND値を削除しなきゃいけないから変わらないかもしれない。ちなみにcomb sortの実装は途中で挿入ソートに切り替えているが、この場合いちいちgapを調べるほうが遅いのでcomb sort11ではない。

なんでこんな事をしているのかというとNativeObjectとNativeArrayのMap,Listインターフェイスを削除して別のラッパークラスにして型が<T extends Scriptable>なら実装がなんであれMapやListとして扱えるようにしたかったから。

じゃあ、これは何でこんな事を始めたかというとNativeObjectとNativeArrayのMap,Listインターフェイスのメソッドが使用頻度の割に邪魔だったので──。

そして、Array.prototype.sortの再実装とたまたま同時進行していてScriptable用の汎用アルゴリズムがあったら便利だなと思いついた次第。Array.prototype.sort用にtim sortを実装し直すのは大変だしこれだけで巨大なのであまり入れたくない。merge sortに近い速度というとheap sortかcomb sortが思いついた。どちらも並列化できない、ランダムアクセスが必要、安定ではないのでメンテが楽なので実装が簡単なcomb sortにしたというわけ。

comb sort+挿入ソートは結構速いと思う。このおかげでrhinoはnashornと比べてabstract operationsのtoStringの実装が遅いということが判明した。

sortの実装でJDKのtim sortを使うとComparison method violates its general contractが回避できないんだけど、これjavaとjsでcomparatorの規約が違うからだよね