モジュールのスクリプトをプリコンパイルしておくと、コンパイルのためのオーバーヘッドをなくなるため、モジュールの初期化が若干速くなります。
% cd /usr/local/pnuts/modules % pnutsc -o pnuts-modules-C.jar pnuts-modules.jarただし、次の点に注意してください。
+演算子による文字列の連結はあまり速くありません。
a = ""
for (i : 1..10000){
a += "."
}
まず、連結したい文字列を順にprint()やprintln()等の関数で表示する関数を定義し、 pnuts.textモジュールのtextGrab()関数に渡します。
function f1(){
for (i : 1..10000){
print(".")
}
}
f2 = textGrab(f1)
f2()
次のようなfor 文のループは、カウンタ変数に対する演算のオーバーヘッドのため、遅くなります。
for(i = 0; i < 1000000; i++){
}
ベンチマーク等、ループのオーバヘッドが気になるケースでは、次のようにするとよいでしょう。
for (i : 0..999999){
...
}
getXXXX()/setXXXX()のようなメソッド呼び出しは、XXXXプロパティへのアクセスに置き換えることで速くなります。
now = Date() longValue = now.time
大きなループでメソッド呼び出しがある場合は、Generatorスタイルかコールバック方式を検討してください。
たとえば、テキストファイルの各行を順に読むコードは、readLines()メソッドを使ってGeneratorスタイルで記述することができ、メソッド呼び出しのオーバーヘッドを軽減することができます。
もう一つの例は、Mapのエントリーを一つずつ取り出して、key-valueペアを表示するものですが、これは、mapFunction関数を使って、コールバック形式で記述することができます。
Pnutsによるループ(遅い) Generatorスタイル(速い) コールバック・スタイル(速い) while ((line = reader.readLine()) != null){ println(line) }for (line : readLines(reader)){ println(line) } readLines(reader, println)m = map() m.a = 1 m.b = 2 m.c = 3 for (pair : m.entrySet()){ println(pair.getKey(), "=", pair.getValue()) } n/a m = map() m.a = 1 m.b = 2 m.c = 3 mapFunction(function (k, v) println(k, "=", v), m)
pnuts.lang.Implementation インタフェースは、スクリプトインタプリタの実装のインタフェースを定義しています。 次のクラスがその実装クラスとしてPnutsの配布パッケージに含まれています。
- pnuts.lang.PnutsImpl
- ASTインタプリタ
- pnuts.compiler.CompilerPnutsImpl
- On-the-fly コンパイラ
- pnuts.ext.CachedPnutsImpl
- Mixed モード。 コンパイル(パーズ)されたスクリプトをキャッシュして再利用する。
On-the-fly コンパイラは、通常はASTインタプリタよりも速く実行されます。 対話的な利用はコンパイルのオーバヘッドが気にならないのでOn-the-flyコンパイラが向いています。
Pnuts が、スクリプトエンジンとしてアプリケーションに埋め込まれ、同じスクリプトが何度も実行される場合、Mixed モードが適しています。 スクリプトをコンパイルするのに、そのスクリプトの大きさに応じて数ミリ秒から数百ミリ秒かかるので、もし、一部のスクリプトが何度も実行されるようならコンパイルされたコードをキャッシュすると効率が向上します。
もし、アプリケーションが決められたスクリプトしか実行しない場合、ASTインタプリタとプリコンパイルされたスクリプトを組み合わせるのが効果的です。コンパイルのためのオーバヘッドがないですし、必要であればコンパイラパッケージを取り去ることもできます。
makeProxy() の利用を検討してください。
スクリプト実行に伴うオーバーヘッド(Reflection APIやメソッド検索等が原因となる)をなくす必要がある場合は、Javaで関数、あるいはload可能なクラスを実装すればよい。 "Javaによる関数の定義" and "load可能なクラス"を参照。