by keigoi #contents * 日本語の解説 [#v3e7eb25] http://d.hatena.ne.jp/keigoi/20101101/1288584308 * ocamljs あとでパッチおくる [#n7dc65d3] - max_int がおかしい(JSのintの範囲をこえる)ので closure compilerで圧縮できない -- 修正ずみ - string_of_float min_floatがSafari/webkitでおかしい -- Safariのバグ。最新のwebkitビルドでは直っている。min_floatは使わないこと - 一部日本語文字列リテラルが化ける ''(未報告)'' -- src/jscomp/jsgen.ml を以下の通りコメントアウトしてみる let utf8_encode s = s (* let len = String.length s in Utf8.from_int_array (Array.init len (fun i -> Char.code s.[i])) 0 len *) -- 日本語文字が"\u5E74"のようにエスケープされてしまうが、出力には影響ない - DateクラスのgetDayメソッド(曜日を取得)がない ''(未報告)'' http://jaked.github.com/ocamljs/doc/Javascript.date-c.html https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getDay - getClientWidth/getClientHeightがない ← DOM標準ではないのでしょうがない? - [[document.stylesheet.insertRule:https://developer.mozilla.org/en/DOM/stylesheet.insertRule]] ほか stylesheetクラスのメソッド - 文字列リテラル中のエスケープシーケンス \x100 などがおかしい ''(未報告)'' - JavaScript quote中の文字列リテラルのエスケープシーケンス \x100 などがおかしい ''(未報告)'' * パフォーマンス [#l5e94b68] - 現時点のocamljsでは関数呼び出しのオーバーヘッドがかなりある -- 関数のカリー化や末尾呼び出しの最適化のため関数呼び出し1回につき2回の間接ジャンプがある(コールスタックが3倍に伸びる) - 通常のPCでは全く問題ない。スマートフォンでもユーザとのインタラクションに影響があるほどではないが、数値計算などで扱うデータの量が多い場合には注意が必要(経験談) - 生成されるJavaScriptは元のOCamlコードの原型が残っているので、Google Closure Compilerによる圧縮と併せて理想的なJavaScriptに落ちるようなOCamlの書き方を探すこともできる -- 特にモジュールをまたいだ呼び出しが最適化されないためListやArrayモジュールのほとんどが低速。効率化するならばまずmap/fold系の高階関数をやめfor式を使い、配列のアクセスを Array.unsafe_get / unsafe_set に置き換えるか、 a.(i)記法を使うならばoc$arefの境界チェックを外してclosure compilerで最適化する。 -- このような最適化をプロファイルの後にごく一部で行うだけで劇的に改善できる。どうしても駄目なときはインラインJavaScript << ... >> を使う。 型がないので注意 ** 多相的な比較は超低速 (.jsのcompare_valを見よ) [#gc65fc90] - min, maxも多相的 - [[奥義・多相転生:http://twitter.com/camloeba/status/15676523910533120]]を使う -- 要するにintやfloat等の型をつければそれ専用の比較が行われるようになる * 圧縮 [#qfb04eb7] ** 基本的な事 [#f3582f34] - 使われていないモジュールはリンクされない。 - Printfはコードサイズを大きくしがち - Randomを使うとInt64がついてくる ** Google Closure Compilerによる 圧縮 [#q511be89] - 以前はclosure compilerでSIMPLE_OPTIMIZATIONすると動かなかった(keigoiの日記参照)が修正された。 - closure compilerでADVANCED_OPTIMIZATIONすると動かないが、 出現する m.$oc などを m['$oc'] に置き換えれば動くようになる。 ''(未報告)'' -- ADVANCED_OPTIMIZATIONはいくらかdead code eliminationや簡単なインライン化もやってくれるので有用。 -- ADVANCED_OPTIMIZATIONでは o.field 形式のフィールドアクセスにおけるフィールド名が全て o.a のように短縮されてしまうが、 o['field'] のように文字列にすれば短縮されない。詳しくはclosure compilerのページ参照 ** 以下よりいいかげんなメモ [#a359a4cb] - ocamljsの進化により無効になるテクニックや、そもそも根拠があいまいなものなど - ADVANCED_OPTIMIZATION前提 *** パターンマッチはclosure compilerで最適化されない [#l346670d] - NG let a,b = expr1, expr2 - OK let a = expr1 and b = expr2 *** let [#u07bba0a] (function(){ var x = ...; expr }()); などと余計な呼び出しが挿入される(が、最適化で除去されることも?)。