カスタム関数のライブラリを作成する際、関数がグローバル名前空間にあるかユーザー定義の名前空間にあるかによって、同じ関数コードのパフォーマンスに著しい違いがあることに気付きました。私の少なくとも1つのイライラするケースでは、同じ名前空間がグローバル名前空間と比較して、カスタム名前空間にあるときに実行するのに7倍の時間がかかります。
多くのアプリケーションでは違いは関係ありませんが、私はこれらの関数を500Kから500万行のテーブルで使用しています。この大きさの違いにより、正常な機能と使用できない機能の違いが生じます。
ここに、違いを例示するいくつかのJSLがあります。
Names Default to Here(1);
Add Custom Functions(
globaltest = New Custom Function(
"Global",
"test123",
Function({x, y, z},
{a, b, c},
a = x;
b = y;
c = z;
Return(c)
)
)
);
Add Custom Functions(
nstest = New Custom Function(
"other",
"test123",
Function({x, y, z},
{a, b, c},
a = x;
b = y;
c = z;
Return(c)
)
)
);
For(i = 1, i <= 10000, i++,
foo = ::test123(i, i, i);
);
For(i = 1, i <= 10000, i++,
foo = other:test123(i, i, i);
);私のマシンでは、:: test123()は143ミリ秒で実行されますが、other:test123は343ミリ秒かかります。
カスタム名前空間に、またはクラスメソッドとして実装することが理想的な関数がいくつかありますが、名前空間の修飾に関連するオーバーヘッドにより、これは受け入れられません。
他の人がこれに気づいていますか?名前空間で修飾された関数の呼び出しを高速化できるテクニック/考慮事項はありますか?
おっと、スクリプトガイドp 896をご覧ください。私は最初にそこを見ることを知っているべきでした。最大のヒントは、速度が重要な場合、関数よりも式を優先することです。また、Return()ステートメントが物事の速度を落とすことに気がつきませんでした。他のヒントはありがたいことに受け取られます。
return()、break()、continue()はすべて同じ動作をします。JSLを読みやすく保守しやすくしますが、実行するとオーバーヘッドが発生します。JSLプロファイラーがホットスポットである場合、それらを指摘するでしょう。
はい、名前空間にもペナルティがあることに気づきましたが、複雑なプロジェクトには喜んで使用します。ホットスポットであることが証明されている単純な変数については、以下のようなコピーイン、コピーアウトの戦略を使用できます。(最初にプロファイルを作成し、速度を落とさないコードを最適化しないでください!)
以下はほとんど名前空間を行使するだけです。ほとんどのコードでは、ネームスペースを使用することでこれほどのペナルティはありません。 しょーた
test = New Namespace(
"test"
);
f = Function( {},
{i, testx},
test:x = 0;
If( useLocal, // speed up by copy-in, copy-out
testx = test:x;
For( i = 1, i < 1e6, i += 1,
testx = testx + 1
);
test:x = testx;
, // no speed up
For( i = 1, i < 1e6, i += 1,
test:x = test:x + 1
);
);
);
useLocal = 0;
t0 = Tick Seconds();
f();
t1 = Tick Seconds();
Show( useLocal, t1 - t0, test:x );//t1 - t0 = 2.76666666666642;
useLocal = 1;
t0 = Tick Seconds();
f();
t1 = Tick Seconds();
Show( useLocal, t1 - t0, test:x );//t1 - t0 = 0.316666666665697;インアウト戦略を試してみます!!!ありがとう、Craige !!!!