indy版 rhino fork

lamdaが遅いといったが厳密には少し違う。
jdk8はjdk7より元々遅く、indy未使用版の現状のrhino forkをjdk8で動かすとjdk7より遅い。
これをlamdaに書き換えるとindy未使用版jdk7より平均的には遅いが、場合によってはスコアが出るのて最終的にindy未使用版jdk7より遅いかどう程度以下に落ち着く。

この点はjdk8でもjdk7並のパフォーマンスを出せる可能性があるが基本的にlamdaでは振るわないということが第一。

第二にMHを使うとSAMクラスの生成を動的にリンクされる直前に行うので平均的なメモリ消費量が下がる(ピークは同じか上がる)。

jdk8でもjdk7と同程度のパフォーマンスが出せて平均的なメモリ消費量が下がるなら採用するかもしれない。どちらにしてもrhino上でのindyの使い方は研究する必要が出てくる。

そもそもjavascritは型変換規則が柔軟なためポリモーフィックメソッドにすら一致させるのが難しい。結局、変数リストは共変配列(Object[])になってしまう。
さらにrhinoはliveconnectがあるのでさらに大変だ。結局MHに型変換丸投げ出来なくてnashornみたいになる。これがある限りindyというかMHはメリットが殆ど無い。

jdk8でperformanceが出ないので使わざるをえないので使ってみるしかない。

rhino forkの話その4

ツール周りに手を付けようかと思ったがまだ他にやることがあった。本家のrhinoに溜まってるpatchをmergeしなければならない。

主にbugfixとperformance関連の修正だがそのままじゃ適応できないので手作業でやっている最中。そろそろ一旦freezeしてバグ取り期間を置く必要があるかも。

rhino forkの話

さて、スロットの検索周りに手をだそうかと思ったらまた色々見つけてしまった。
ASTとパーサー周りに色々問題がある。Nodeクラスが必要なところでAstNodeに依存してたり結構深い問題。
あと実装に無駄が多いのでいじれば早くなるがメモリ食ってしまう。なのでいじれない。そこで後回しにする。

というわけでスロット周りに戻ってきたはいいが、こっちはこっちでマルチスレッド周りの処理が汚くて触りたくない状況に……。
rhinoはマルチスレッドで動いているのでここにバグを入れると、やること多すぎてバグ取りまで手が回らないのでこれも後回しということに。

そんなこんなでソースコードとjavadocコメントのクリーンナップを追加。あと、トピックブランチ切ってた新しいオブジェクトホスティング機構を取り込んだ。
そこら辺に関するサンプルとbenchmarkの更新が追加されている。そろそろtagging予定。

今後の予定はtool周りの改良。ここでの大本命はdebugger。今後のことを考えてサポートバージョンをjava 8,9,10に置いているので必須バージョンはそれぞれ、6,7,8となる。
そこでGUIにはAWT/SwingではなくてJavaFXを使う。nashornのバグ取りとSceneBuilder 2.0があと2ヶ月で間に合うかという問題は別としてjava8ではjavafx8なのでfx2.*系と互換性がない。
よってjava 6,7は引き続きSwingとなる。しかし、text絡みのbugfixは同じ部分を修正しなければならないかもしれないので従来のtool群も修正が入る可能性がある。

早くEOLにな~れ!

あとコードがすっきりするのでGUIにはラムダ式使う。GUIにレイテンシなんて、そんなの関係ないよ!

問題はjava8そのものがjava7よりパフォーマンス悪いことじゃないだろうか。

ところでこのforkではパフォーマンスに影響を与える根本には一切手をれていない。しかし、v8-benchmarkのスコアでnashornの3倍遅いから2倍遅いまで向上しているので2倍の差なら埋められると思う。ただウォームアップすると4倍遅いまで開くのでこれは追いつけないかもしれない。sun-spiderも1000ms台を安定して出したい。nashornみたいにメモリ使えば出来ることはまだあるんだけどメモリは使いたくない。元より組み込みでヌルヌル動くrhinoだからそのままの特性を維持したいので。

あとビルドシステムをGradleに変えるかもしれない。

java7とjava8でパフォーマンス特性が──

違うのでOctane-v2.0のbenchmarkごとのスコアが変わってしまう。
deltablueのスコアが上がるが他が落ちてしまう。とくにcryptoとsplayあたりが格段に落ちる。
indyっぽい特性なのでこれは多分、java8の中でindyを使うようになったんじゃないかと思う。

さてどうするか、java7とjava8でsun-spiderのスコアが200msから300msくらい違うんだが……。

rhino forkとnashorn

jdk8_b121に更新したらnashornのv8-benchmarkのスループットが安定して消費メモリが増えていた(1G超えるんだが)。なにか変わったみたい。
現状nashornはv8-benchmarkでrhinoの二倍のスコアがあるけどこれくらいなら遅い部分をどうにかすれば追いつけそう。

今のrhino forkは前の投稿から少し進展して、未実装だった部分を少し実装したのとチューニングをやってみた。前のスコアが650~700位だったのが670~720位に上がった。
jdk8_b121のnashornで1500超え位だから始めに言ったようにだいたい二倍となる。元々のrhinoはW-03で動くぐらいメモリ消費が少なかったがビットフィールド使うのやめて列挙使ったりパフォーマンス・チューニングしたら消費量がかなり増えてしまったがGCの起こり方でかなり変わってしまうのが難点、これのせいでチューニングしづらい。

sun-spiderの方はそうでもなくむしろGCの頻度が上がって消費メモリが減ったが、GCの頻度が上がった割にレスポンスが早くなっている。単純にレイテンシが小さくなったのかGCとの相性かjavaのVMは挙動が読めない。ただ、消費メモリが増える以前の変更では1100ms~1000ms出ていたのが1300ms~1200ms位に落ちているのでやはり消費メモリが元より増えている影響は出ている。ただGC回数が増えた分回収されたメモリが増えたんだろう。Full GCの頻度が下がってScavenge GCの頻度が上がったんだろうか?-verbose:gc -XX:+PrintGCDetailsでも追加してテストする必要がありそう。

そろそろ、スロット周りに手を出したいんだけどrhinoには単純な置き換えでperformanceを改善できるコードと、一見遅そうに見えて今時のPCにはどうって事もないコードと、もっと早そうなコードもありそうなのに実際置き換えてみると元のコードが最適解の魔法が山ほどあるのでちまちまと進めるしかありません。gitでresetしまくってます。

スロット周りにはちょっとした魔法を仕込んでperformanceを上げておきましたが本命ではないので早く本命のコードを変更したいです。

rhino fork その2

ラムダ式遅すぎて話にならんかったんな・・・。

メモリ使用量戻ったけどrichardsとdeltablueだけスコア上がって他はかなり下がってしまった。
AOTコンパイラで4-A案(AOTコンパイラでindy)に変更してこっちは後回しにしてメモリ消費の削減とかスロット周り改善を先にやろう。

しかし、バイトコードレベルでチューニングしてるから迂闊にgenericsとか使うとinvoke*インストラクションコードが遅い。
なんどかソースコードの大部分を巻き戻したけどgitにして良かった。

Rhino forkの近況とメモ

IdScriptableObjectとIdFunctionCallをやっと廃止した。長かった。
今はバグ取りの最中なのでまだgithubにpushしてない。

実行速度とは直接関係ないところだがこの影響でV8-benchmarkのスコアが一部を除いてだいたい200くらい上がった。
richardsとdeltablueのスコアが5,60程度しか上がらなかったので全体ではあまり変化はない。一部テストはGC次第でnashornに近づくことが出来た。

元からだけど、SplayLatencyにいたってはnashornより高スコアとなった。このテストは低スコアだとGCの停止時間が長いとあったのでrhinoの方がシステムへの負荷は低くなるはず。
あとnative objectsの関数の実行は元からrhinoの方が速いのでrichardsとdeltablueのようなstandaloneな言語でアプリケーションを作るようなコードは向いてないがバッチ処理のような事は向いていることがわかる。

しかし、メモリ使用量が増えてしまった。これは問題。

今後のプランは──

1)バグ取り
2)ここまでtaggingしてpush
3)スロット周りの高速化(これが大本命)
4-A)indy対応
4-B)java8対応
5)ES6の一部対応、javascript関数をFunctionInterfaceとして扱えるようLiveConnectを拡張
6)ツール群の刷新

4-AのプランだとCodeGenでindy吐くように変更、4-Bのプランだとラムダ式使ってメモリ消費量を改善できるかもしれないのと自前でindy吐くより簡単かもしれない。
どっちもまだ少しも試してない。ラムダ式使うとメモリ減るかもしれないのは現状が定数固有の振る舞いを使って実装されているために1メソッド=1クラス+1インスタンスのメモリを食うから。
これのせいで100Mbyte近く増えてしまったが色々改善、String.prototypeのDOM level 0関連の関数を削除したらかなり戻った。

5)のjavascript関数をFunctionInterface~はnashornに実装されてて便利だったため。ついでにメソッド参照とコンストラクタ参照も扱えるようにしたい。

6)はコンパイラ、REPL、スクリーンエディタ、デバッガの刷新。もし、4-Aプランを採用したときは実行時にスクリプトをコンパイルしていてはnashornのようにリソースを食い過ぎるので、おそらく、バイトコード生成はAOTコンパイラでやる予定。それにともなってスクリプトの64K limit回避とload関数のコンパイル済みスクリプトの読み込み方法の改善も必要。

今までのRhinoはjava 1.4以降でコンパイル出来たがこのforkでは1.6以降が必須となる。
これはJEP182に合わせるためでrhinoではretrotranslatorを使って1.4に対応していたがJEP182ではjsr14が削除されるので結果それに追従して最低versionが1.6となる。

とまあこの辺に