気ままな一言
2008年04月02日
スクリプトの高速化 その1
前回の関数の補足ついでにスクリプトの処理速度についてです。
こっちにあるmax()と
下記関数の実行時間を比較してみます。
どちらもリストに含む数値の最大値を求める関数です。
仮に前者をA、後者をBとしておきます。
Aはリストのデータを降順ソート(大きい順に並び替え)して先頭の値を返しています。
Bは単純に比較しているだけです。
想像してもわかる通り、一般的にソートは重い処理ですが、見かけ上は関数2個分です。
リストに渡すデータ数は400個のランダムデータです。
さて、どちらがどの程度速いでしょうか?
とまぁ、そんな問題を出すまでもなく
公開したAが速いのはバレバレなので、さっさと結果を見てみましょう。
結果
A …… 0.065191
B …… 7.144770
100倍以上の差が出ました。
まぁそういう訳です。
普通にスクリプトではないプログラミング言語で同じようなことをしたら、Bのような方法のほうが速くなります。
考えてみればわかるようにソートするにはBのような全検索処理も必要になるからです。
では、何故Aの方が速いかというと、それは行数が多いからです。
いい加減な理由かと思いますが、そうなのです。
LSLの仕様として組み込まれた処理は内部の最適化された処理として動作します。
一方、スクリプトとして書いたものはセカンドライフというアプリケーションの上で解析されながら動作します。
この差が非常に大きいのです。
既存の関数だけで同じようなことができるのであれば、アルゴリズムに関係なくその方が速くなるのです。
正直、ここまで差が出るとは思いませんでしたが。
ただ、今回のAには欠点があります。
それはリストの数を400という中途半端な数にしたことに答えがあります。
Aではこれ以上増やすとメモリが足りなくてソートができないからです。
(そんな個数を扱うことはそうそうないとは思いますが)
要するに地味な努力が速度UPに繋がったり、SIMの負荷を軽減したりする訳です。
実用上では本当に地味にしか変わりませんが、そんなことは言わないで下さい。(汗)
続きを読む
こっちにあるmax()と
下記関数の実行時間を比較してみます。
float max(list lst) { integer i; integer len = llGetListLength(lst); float m = llList2Float(lst, 0); float n; for (i = 1; i < len; i++) { n = llList2Float(lst, i); if (m < n) { m = n; } } return m; }
どちらもリストに含む数値の最大値を求める関数です。
仮に前者をA、後者をBとしておきます。
Aはリストのデータを降順ソート(大きい順に並び替え)して先頭の値を返しています。
Bは単純に比較しているだけです。
想像してもわかる通り、一般的にソートは重い処理ですが、見かけ上は関数2個分です。
リストに渡すデータ数は400個のランダムデータです。
さて、どちらがどの程度速いでしょうか?
とまぁ、そんな問題を出すまでもなく
公開したAが速いのはバレバレなので、さっさと結果を見てみましょう。
結果
A …… 0.065191
B …… 7.144770
100倍以上の差が出ました。
まぁそういう訳です。
普通にスクリプトではないプログラミング言語で同じようなことをしたら、Bのような方法のほうが速くなります。
考えてみればわかるようにソートするにはBのような全検索処理も必要になるからです。
では、何故Aの方が速いかというと、それは行数が多いからです。
いい加減な理由かと思いますが、そうなのです。
LSLの仕様として組み込まれた処理は内部の最適化された処理として動作します。
一方、スクリプトとして書いたものはセカンドライフというアプリケーションの上で解析されながら動作します。
この差が非常に大きいのです。
既存の関数だけで同じようなことができるのであれば、アルゴリズムに関係なくその方が速くなるのです。
正直、ここまで差が出るとは思いませんでしたが。
ただ、今回のAには欠点があります。
それはリストの数を400という中途半端な数にしたことに答えがあります。
Aではこれ以上増やすとメモリが足りなくてソートができないからです。
(そんな個数を扱うことはそうそうないとは思いますが)
要するに地味な努力が速度UPに繋がったり、SIMの負荷を軽減したりする訳です。
実用上では本当に地味にしか変わりませんが、そんなことは言わないで下さい。(汗)
続きを読む
2008年03月19日
LSLの色付け
ブログに書いたLSLを自動的に色付けしてくれるツールがあるようで
へぇ~と思っていました。
色付け以外の機能も付いていて面白そうです。
※ 詳しくはこちらのブログで~
sabroさん
Jvnさん
ですが、今の私がこれを導入するには
JavaScriptなどのファイルをアップする別サーバーから用意する必要があるので、、
う~ん、また今度でw
とりあえず色付けすると見た目が良くなるので、当面自前で色付けしてみます^^
まぁそんなにスクリプトを載せることもないでしょうし。。
ただ、SLの配色は暗くて好きではないので
勝手な配色にします。
きっとこれよりハデハデになる予定ですが、まぁ苦情があったら変えます(^_^;
(余談ですが、海外のエディタはLSLに関わらずこの暗めの配色が多いです)
へぇ~と思っていました。
色付け以外の機能も付いていて面白そうです。
※ 詳しくはこちらのブログで~
sabroさん
Jvnさん
ですが、今の私がこれを導入するには
JavaScriptなどのファイルをアップする別サーバーから用意する必要があるので、、
う~ん、また今度でw
とりあえず色付けすると見た目が良くなるので、当面自前で色付けしてみます^^
まぁそんなにスクリプトを載せることもないでしょうし。。
ただ、SLの配色は暗くて好きではないので
勝手な配色にします。
きっとこれよりハデハデになる予定ですが、まぁ苦情があったら変えます(^_^;
(余談ですが、海外のエディタはLSLに関わらずこの暗めの配色が多いです)
2008年03月09日
スクリプトのメモリチェック
スクリプトには今のところ16KBとというメモリ(ヒープ)の制限があります。
しかし、世にあるSL内のスクリプトで
メモリチェックしているスクリプトって少ないと思います。
大抵は不要なので問題ないのですが、
リストなどに追加され続けるものに関しては気にする必要があります。
メモリが無くなるとこんなメッセージが出ます。
Script run-time error
Stack-Heap Collision
原因は違うかもしれませんが、見かけたことはあると思います。
こうなってはもう正常な動作はしなくなります。
そこでメモリが少なくなったら解放してあげる必要があるのですが、
実験をしていてあることに気付きました。
メモリの解放されるタイミングがわかりません。
少なくともスクリプト実行中(スクリプト上の処理中)には解放されないようにみえます。
例えば、こんなことをすると無限ループに陥ります。※1
メモリ対策をしたばっかりにフリーズします。
ちなみに関数の処理やメモリの再確保のタイミングは内部処理に関連するみたいなので
よくわかりませんでした。
全然メモリ残量が減らなかったり、突然予想以上に減ったりすることもあるので
余裕をみておいたほうがいいです。
※1 放置し続けたらいつの日か解放されてループを抜けるのかもしれませんが、どちらにしても実用的ではありません。
しかし、世にあるSL内のスクリプトで
メモリチェックしているスクリプトって少ないと思います。
大抵は不要なので問題ないのですが、
リストなどに追加され続けるものに関しては気にする必要があります。
メモリが無くなるとこんなメッセージが出ます。
Script run-time error
Stack-Heap Collision
原因は違うかもしれませんが、見かけたことはあると思います。
こうなってはもう正常な動作はしなくなります。
そこでメモリが少なくなったら解放してあげる必要があるのですが、
実験をしていてあることに気付きました。
メモリの解放されるタイミングがわかりません。
少なくともスクリプト実行中(スクリプト上の処理中)には解放されないようにみえます。
例えば、こんなことをすると無限ループに陥ります。※1
メモリ対策をしたばっかりにフリーズします。
while (llGetFreeMemory() < 1024) { lst = llDeleteSubList(lst, 0, 0); // 先頭から1つ削除 }ループを抜けるような仕組みにするか、別の方法にする必要があります。
ちなみに関数の処理やメモリの再確保のタイミングは内部処理に関連するみたいなので
よくわかりませんでした。
全然メモリ残量が減らなかったり、突然予想以上に減ったりすることもあるので
余裕をみておいたほうがいいです。
※1 放置し続けたらいつの日か解放されてループを抜けるのかもしれませんが、どちらにしても実用的ではありません。