Difference between revisions of "LSL Script Efficiency/ja"

From Second Life Wiki
Jump to navigation Jump to search
m (→‎効率: changed to link translated pages)
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Multi-lang}}
{{Multi-lang}}
'''現在翻訳作業中です...'''(これは翻訳作業者が、作業中であることを明示するために挿入した一文です。)
<div style="float:right;">__TOC__</div>{{LSL Header/ja}}
<div style="float:right;">__TOC__</div>{{LSL Header/ja}}


Line 7: Line 6:
<div style="padding: 0.5em;">
<div style="padding: 0.5em;">


Efficiency is how much resource a particular script uses to accomplish a goal.  This often goes hand-in-hand with speed of execution, but not always.
効率は、特定のスクリプトが目標を成し遂げるためにどの程度のリソースを用いるか、ということです。これは、しばしば動作速度と相互して作用しますが、常にそうなるわけではありません。


Things to watch out for, in rough order of importance:
気をつけるべき、劣悪な事例


* Using a lot of scripts to accomplish something.  See Efficient Design.
* 何かを成し遂げるためにスクリプトを多く使う。 効率的デザインを参照
* [[llSleep]] - This function uses up 0.2 to 0.3 ms per frame while the script sleeps, timers are much better.
* [[llSleep]]をスクリプトを停止させる間、フレームあたり0.2から0.3ミリ秒以上使用する。timerでもよし。
* Short frequency timers (<5 sec)
* 短く、頻繁にtimerをかける。(5秒以内)
* Listen - especially to the 0 channel
* Listenは普段から0チャンネル。
* Changing textures often (Others have to download them)
* しばしばテクスチャを切り替える。(ほかにテクスチャをダウンロードしなければならない場合)
* Inappropriate use of server/physical rotations instead of omega
* 不適切にomegaの代わりにサーバ/物理にて回転させる。
* Event handlers which are not needed (touch, collision, ...)
* イベントハンドラをいずれも使用しない (touch、collision、...
* Large amount of email or IM
* emailもしくはIMの規模の大きさ
* Inefficient algorithms (like linear search)
* 能率的でないアルゴリズム(順次探索のような)
* Busy (polling) loops
* かたっぱしからループさせっぱなし


</div></div>
</div></div>
<div id="box">
<div id="box">


== 効率的な設計 ==
== 効率的デザイン ==
<div style="padding: 0.5em;">
<div style="padding: 0.5em;">


Each idle script in an object adds 0.001 to 0.003 milliseconds per frame of script time usage.  Less scripts is better.
オブジェクト内の各アイドル状態のスクリプトは Script timeの使用量へ、フレームあたり0.001から0.003ミリ秒追加します。少ないスクリプトファイル数が推奨されます。


* If you need to have a bunch of "buttons", don't put a script in each prim.  Use [[llDetectedLinkNumber]] to detect which button was touched from your main script instead. 
* もしボタンの一覧を持つ必要がある場合、プリム毎にスクリプトをいれてはいけません。 スクリプトの代用に、それぞれのボタンをタッチされた場合に検出する[[llDetectedLinkNumber/ja|llDetectedLinkNumber]]を使用しましょう。
* If you need to change color, alpha, or texture of child prims, do not put a script in each prim.  Instead use [[llSetLinkAlpha]], [[llSetLinkColor]], [[llSetLinkTexture]], or [[llSetLinkPrimitiveParams]].
* もし子プリム群の色や透過率、テクスチャを変える必要がある場合、それぞれのプリムにスクリプトを入れてはいけません。代わりに[[llSetLinkAlpha/ja|llSetLinkAlpha]][[llSetLinkColor/ja|llSetLinkColor]][[llSetLinkTexture/ja|llSetLinkTexture]]、か[[llSetLinkPrimitiveParams/ja|llSetLinkPrimitiveParams]]を使用しましょう。
* '''Never''' put a script in each prim (of a large linkset) that listens on channel 0 (or any other channel).  This is probably the worst thing you can do for efficiency.  Unfortunately it is all too common.
* 0チャンネルでのlistenを各プリムに入れることは'''ありえません'''。これは効率のために最も悪いことであるのは確かです。全てにおいて不適当なことです。
* Consider using [[XyzzyText]] instead of [[XyText]].
* [[XyText]]の代わりに[[XyzzyText]]を使用しましょう。


The bottom line is, if you find yourself tempted to put a script in each prim, stop and think about how you could do it differently with less scripts.  There is almost always an alternative.  It is up to you to decide whether the alternative is a viable one for your application.
最後に、もし各プリムにスクリプトを入れることの自動化を試みているなら、中断して少ないスクリプト数で異なるやり方と取るべきだと思いましょう。大概常に別の選択肢があります。アプリケーションにとって有効な選択肢であるかどうか決めるのはあなた自身です。


</div></div>
</div></div>
<div id="box">
<div id="box">


== Micro-optimization ==
== 細かい最適化 ==


There are many ways to speed up scripts, such as using ++a instead of a++, however, most of these micro optimizations might not hold true in the future.
a++の代わりに++aを使うように、スクリプトのスピードアップの方法は数多く存在しますが、これらの多くの細かい最適化は将来においても保障されているわけではありません。




== How Fast Does That Code Run ==
== どのようにしてコードを早く動かすか ==
<div style="padding: 0.5em;">
<div style="padding: 0.5em;">


The following code will get the time for each function call in millis.
補足されているコードは、ミリ秒で各関数を呼んだ際かかるであろう時間を取得するものです。


Please first propose changes to the [[Talk:LSL_Script_Efficiency|discussion]] tab. Please do not change the code here without discussion, as any small change could reduce the accuracy of measurements. Please note this code and its comments should exactly match the code and comments presented by the [[Efficiency Tester]] page.
始めに、[[Talk:LSL_Script_Efficiency|discussion]]を変えることを提案します。正確な計測ではない些細な変化によるもの、もしくは議論なしでのコード変更はしないでください。[[Efficiency Tester]]にコードとコメントを、正確にそのまま記録してください。


Thanks to {{User|Xaviar Czervik}} for the original code, thanks to {{User|Strife Onizuka}} for tuning the code to produce more accurate measurements, and thanks to the other contributors listed in the history of this article.
オリジナルコードは{{User|Xaviar Czervik}}の提供で、更に正確な計測を行えるコードになったのは{{User|Strife Onizuka}}のおかげで、そして、この箇条書きの経過を一覧化した方々の力添えによって成り立っています。


<pre>
<pre>
//IMPORTANT: Only perform tests in an empty region.
//重要: 空のregionでのみテストしています。
// To reduce contamination and be sure to wearing no attachments.
// 重複しているものを削減して、必ずアタッチメントを外してください。
// Preferably do tests in a private sim with one on it.
// 願わくばプライベートシム上にてテストを行ってください。
// Don't move while performing the test.
// テストを行っている間は動かないでください。
// There is a margin of error so run the tests multiple times to determine it.
// 誤差の余裕を持たせるため、複数回に分けてテストを行います。


integer time() { // count milliseconds since the day began
integer time() { // count milliseconds since the day began
Line 102: Line 101:
<div style="padding: 0.5em;">
<div style="padding: 0.5em;">


The following data was collected using the above function in a recently deployed empty (though not private) sim, with only that one script running in a HUD attachment. 20 tests of each were run and averaged.
以下のデータは先ほど展開した空の(完全にプライベートではない)SIMで、HUDアタッチメントのスクリプトのみを走らせて、上記の関数を使って収集されました。20回程度のテストの平均値です。
   ++a:    0.173780 ms    std. dev.:  0.003393 ms
   ++a:    0.173780 ms    std. dev.:  0.003393 ms
   a += 1:  0.181720 ms    std. dev.:  0.013267 ms
   a += 1:  0.181720 ms    std. dev.:  0.013267 ms
   a++:    0.243500 ms    std. dev.:  0.013816 ms
   a++:    0.243500 ms    std. dev.:  0.013816 ms
Thus a++ takes 40% longer to execute than ++a (rough estimate).
このように、a++ ++a よりも(概算で)実行に40%長くかかります。


While the following data is correct, the function above was not used. A slightly less optimized version written by {{User|Xaviar Czervik}} was used. If someone could please repeat the tests with the function above.
以下のデータの時間は、上記の関数を使用していない不正確なものです。{{User|Xaviar Czervik}}によって書かれた、そこまで最適化されていないものを使用しました。もし誰かが繰り返しテストするなら、上記の関数を用いてください。


   ++a:    0.364700 millis
   ++a:    0.364700 millis
Line 114: Line 113:
   a++:    0.413700 millis
   a++:    0.413700 millis


Testing the same function in for loops:
ループで同じ関数をテストした結果
   ++a:    0.358370 millis
   ++a:    0.358370 millis
   a += 1:  0.351200 millis
   a += 1:  0.351200 millis
   a++:    0.424600 millis
   a++:    0.424600 millis


[[llOwnerSay]] v. [[llSay]] v. [[llShout]] v. [[llWhisper]] (Channel 0 where applies):
[[llOwnerSay/ja|llOwnerSay]] [[llSay/ja|llSay]] [[llShout/ja|llShout]] [[llWhisper/ja|llWhisper]] (0チャンネル状態にて)
   llOwnerSay(): 4.359000 millis
   llOwnerSay(): 4.359000 millis
   llWhisper():  5.201000 millis
   llWhisper():  5.201000 millis
Line 125: Line 124:
   llShout():  14.877000 millis
   llShout():  14.877000 millis


Different Channels ([[llSay]]() Used for all):
異なるチャンネルにて([[llSay/ja|llSay]]()を使用):
   -100000000: 1.226400 millis
   -100000000: 1.226400 millis
   -100000:    1.254300 millis
   -100000:    1.254300 millis
Line 136: Line 135:
   100000000:  1.228700 millis
   100000000:  1.228700 millis


Amount of text ([[llSay]]() and Channel 1 used for all):
文字量の差([[llSay/ja|llSay]]()にて1チャンネルを使用):
<pre>
<pre>
   1 Character:    1.242300 millis
   1 Character:    1.242300 millis

Latest revision as of 09:34, 30 June 2008

効率とは

効率は、特定のスクリプトが目標を成し遂げるためにどの程度のリソースを用いるか、ということです。これは、しばしば動作速度と相互して作用しますが、常にそうなるわけではありません。

気をつけるべき、劣悪な事例

  • 何かを成し遂げるためにスクリプトを多く使う。 効率的デザインを参照
  • llSleepをスクリプトを停止させる間、フレームあたり0.2から0.3ミリ秒以上使用する。timerでもよし。
  • 短く、頻繁にtimerをかける。(5秒以内)
  • Listenは普段から0チャンネル。
  • しばしばテクスチャを切り替える。(ほかにテクスチャをダウンロードしなければならない場合)
  • 不適切にomegaの代わりにサーバ/物理にて回転させる。
  • イベントハンドラをいずれも使用しない (touch、collision、...)
  • emailもしくはIMの規模の大きさ
  • 能率的でないアルゴリズム(順次探索のような)
  • かたっぱしからループさせっぱなし

効率的デザイン

オブジェクト内の各アイドル状態のスクリプトは Script timeの使用量へ、フレームあたり0.001から0.003ミリ秒追加します。少ないスクリプトファイル数が推奨されます。

  • もしボタンの一覧を持つ必要がある場合、プリム毎にスクリプトをいれてはいけません。 スクリプトの代用に、それぞれのボタンをタッチされた場合に検出するllDetectedLinkNumberを使用しましょう。
  • もし子プリム群の色や透過率、テクスチャを変える必要がある場合、それぞれのプリムにスクリプトを入れてはいけません。代わりにllSetLinkAlphallSetLinkColorllSetLinkTexture、かllSetLinkPrimitiveParamsを使用しましょう。
  • 0チャンネルでのlistenを各プリムに入れることはありえません。これは効率のために最も悪いことであるのは確かです。全てにおいて不適当なことです。
  • XyTextの代わりにXyzzyTextを使用しましょう。

最後に、もし各プリムにスクリプトを入れることの自動化を試みているなら、中断して少ないスクリプト数で異なるやり方と取るべきだと思いましょう。大概常に別の選択肢があります。アプリケーションにとって有効な選択肢であるかどうか決めるのはあなた自身です。

細かい最適化

a++の代わりに++aを使うように、スクリプトのスピードアップの方法は数多く存在しますが、これらの多くの細かい最適化は将来においても保障されているわけではありません。


どのようにしてコードを早く動かすか

補足されているコードは、ミリ秒で各関数を呼んだ際かかるであろう時間を取得するものです。

始めに、discussionを変えることを提案します。正確な計測ではない些細な変化によるもの、もしくは議論なしでのコード変更はしないでください。Efficiency Testerにコードとコメントを、正確にそのまま記録してください。

オリジナルコードはXaviar Czervikの提供で、更に正確な計測を行えるコードになったのはStrife Onizukaのおかげで、そして、この箇条書きの経過を一覧化した方々の力添えによって成り立っています。

//重要: 空のregionでのみテストしています。
// 重複しているものを削減して、必ずアタッチメントを外してください。
// 願わくばプライベートシム上にてテストを行ってください。
// テストを行っている間は動かないでください。
// 誤差の余裕を持たせるため、複数回に分けてテストを行います。

integer time() { // count milliseconds since the day began
    string stamp = llGetTimestamp(); // "YYYY-MM-DDThh:mm:ss.ff..fZ"
    return (integer) llGetSubString(stamp, 11, 12) * 3600000 + // hh
           (integer) llGetSubString(stamp, 14, 15) * 60000 +  // mm
           llRound((float)llGetSubString(stamp, 17, -2) * 1000000.0)/1000; // ss.ff..f
}

default {
  state_entry() {
    llOwnerSay((string) llGetFreeMemory());

    //test variables
    float counter;

    //framework variables
    float i = 0;
    float j = 0;
    float max = 10000; // 2ms of work takes 20 seconds to repeat 10,000 times, plus overhead

    float t0 = time();
    do {

      //test
      counter += 1;
      
    }while (++i < max);
    float t1 = time();
    do ; while (++j < max);
    float t2 = time();//remove the time required by the framework
    float elapsed = ((t1 - t0) - (t2 - t1))/max;
    llOwnerSay("The function in the loop took a total of " + (string)elapsed + " milliseconds.");
  }
}

効率

以下のデータは先ほど展開した空の(完全にプライベートではない)SIMで、HUDアタッチメントのスクリプトのみを走らせて、上記の関数を使って収集されました。20回程度のテストの平均値です。

  ++a:     0.173780 ms    std. dev.:  0.003393 ms
  a += 1:  0.181720 ms    std. dev.:  0.013267 ms
  a++:     0.243500 ms    std. dev.:  0.013816 ms

このように、a++ は ++a よりも(概算で)実行に40%長くかかります。

以下のデータの時間は、上記の関数を使用していない不正確なものです。Xaviar Czervikによって書かれた、そこまで最適化されていないものを使用しました。もし誰かが繰り返しテストするなら、上記の関数を用いてください。

  ++a:     0.364700 millis
  a += 1:  0.346900 millis
  a++:     0.413700 millis

ループで同じ関数をテストした結果

  ++a:     0.358370 millis
  a += 1:  0.351200 millis
  a++:     0.424600 millis

llOwnerSayllSayllShoutllWhisper (0チャンネル状態にて)

  llOwnerSay(): 4.359000 millis
  llWhisper():  5.201000 millis
  llSay():      5.226000 millis
  llShout():   14.877000 millis

異なるチャンネルにて(llSay()を使用):

  -100000000: 1.226400 millis
  -100000:    1.254300 millis
  -100:       1.296100 millis
  -1:         1.292400 millis
  0:          5.226000 millis
  1:          1.242300 millis
  100:        1.249100 millis
  100000:     1.219700 millis
  100000000:  1.228700 millis

文字量の差(llSay()にて1チャンネルを使用):

   1 Character:    1.242300 millis
   10 Characters:  1.309700 millis
   100 Characters: 1.965600 millis