ASパフォーマンス検証 getter と 直接参照の差は?
FxUG勉強会であったひがさんの「How to hack ActionScript」をまねして
ちょっと疑問に思っていたことをやってみました。
クラスの中で外から値を変更させないようgetterで参照のみプロパティ作成することが結構あるのですが
クラスの中で、getterで参照するのと直接参照するのとどのくらい違うのかなぁと思っていたのですよ。
とりあえず、getterが速いという事はありえない。
その差がたいしたことなければよいのだけど・・・。
で、下のようなサンプルを作ってみました。
#ちなみにActionScriptプロジェクトのクラスです。
package { import flash.display.Sprite; import flash.utils.Timer; import flash.utils.getTimer; public class Test extends Sprite { private var _value:int; public function get value():int{ return _value; } public function Test() { var startTime:Number= getTimer(); var count:int=0; _value=1; for(var i:int=0;i<1000000;i++){ //問題 _valueとvalueで参照したときの差は? count+=value; } trace("Time",getTimer()-startTime); } } }
結果は
_valueとした場合は100ms程度
valueとした場合は400ms程度
その差 4倍。
おや?思っていた以上です。
これって、外部から参照する場合もいえますよね?
たとえばArray.length
for(var j:int=0;j<list.length;j++){}
と
var count:int=list.length for(var j:int=0;j<count;j++){}
これも4倍〜5倍
いろいろ試してみました。
下記サンプルのコメント化してあるループをひとつずつ試すと次のとおり
var startTime:Number= getTimer(); var list:Array = new Array(["a"],["b"],["c"]); var count:int=list.length; //(※のとき以外はコメント) var j:int; for(var i:int=0;i<1000000;i++){ /*for( j=0;j<count;j++){ //99ms※ }/* /*for(j=0;j<list.length;j++){ //495ms }*/ /*for( j=0;j<count;j++){ list[j]; //403ms※ }*/ /*for(j=0;j<list.length;j++){ list[j]; //821ms }*/ /*for each(var o:Object in list ){ o; //756ms }*/ } trace("Time",getTimer()-startTime);
Flash CS3でパブリッシュしたSWFをFlexのSWFLoaderで読む
やってみました。
SWFLoader.content["インスタンス名"]
でswfにあるインスタンスをとってこれましたよ。
何したのかって言うと、たくさんswfにアイコン登録しておいて
必要なものだけ呼び出して配置しただけですが・・・。
- swfの入れ替えだけで動的に変えたかった。
- 一つ一つパブリッシュするの面倒
- 複数のパーツ組み合わせたアイコンの作成管理ができる
CSSと言う手もあったのだけど、
CSSコンパイルするのが面倒だったので・・・。
見た感じ、MovieClipを拡張したクラスをFlashのシンボルにリンケージ指定して
同じクラスをFlex側で参照すれば制御もできるんじゃない?
でも、普通にコンポーネントを作るだけなら
上条さんが紹介してくれたやり方がよいのかな・・・。
http://weblogs.macromedia.com/akamijo/archives/2007/04/flex_flash_inte.cfm
ヘッダーにチェックボックス
sato-shiさんのところにのってました
チェックボックス付きヘッダ - Flex Coder
確かに3ステート欲しいよね?
つかいたかったので、作ってみましたよ。
http://www.chisa-to.com/DataGridSample/datagridtest.html
でもちょっと納得いかない。
チェックボックスにスキン適用したときはどうしようとか
3ステートチェックボックスに
フォーカスあたったときのスタイル変更
Chengeイベント
ラベル
混在時にクリックしたときonにするのかoffにするのかの設定
作っていないとか
ライブラリにするのにmxmlじゃなくてAS化したかったのだけど
HeaderRendererのときはうまく表示できなかったとか・・・
(なぜかwidthが0になる・・・)
とりあえず、要件は満たしてるよね。
Flexからブラウザを閉じる
Flexに移行したシステムに「終了」ボタンがあるのを忘れてましたよ。
「終了」=ブラウザを閉じる
なので、なんてことはない。
AS3ではExternalInterfaceからJavaScriptをコールできる。
private function end():void
{
if (ExternalInterface.available){
ExternalInterface.call("window.close",null);
}
else{
Alert.show("エラーが発生しました。\nブラウザの閉じるボタンで終了してください。");
}
}
これやるとIEでは
「このウィンドウを閉じますか?」
と、確認ダイアログが出てきてしまうのだけど、
普通にJavaScriptでやっても出るし、
終了の確認になるからまぁいいか。
#あばうとだぁ・・・。
ん?理論上JavaScriptのpromptも出せるよね?
デフォルトでpromptみたいな簡易入力ダイアログのクラスないのよね。
(私が知らないだけ?)
昨日それで悩んだのよねぇ・・・。
AlertのソースこぴってPromptクラス作ったからまぁいいか・・・。
入力規制もできるようにしたしね。
一度にたくさんの子供を追加する
UIComponentにたくさんのSpriteを追加する実験 - chisa-to あれこれ
で、addChildがボトルネックになっている話を書きました。
だいぶ前に解決していたけど、書いてなかったね。
原因はASはシングルスレッドだから。
ループを繰り返しているうちは描画メソッドが実行されないのですよ。
繰り返し処理は1フレーム内で収まるようにしてあげないと
めちゃくちゃ遅くなるわけです。
じゃ、どうするのかというと、
callLaterメソッドを使うのですよ。
マニュアルちゃんと読めっ!って自分で突っ込んでしまった
private function commitAddNewItems():void{
var count:int=0;
var maxCount:int=100;//100回、もしくは リストが空になるまで追加処理を行う
while(maxCount>count && createList.length>0){
addChild(createlist.pop());
count++;
}if(createlist.length>0){
//次の画面更新処理のときに追加処理を再開
callLater(commitAddNewItems);
}
}
こうすると、追加している最中にも画面更新が発生するので
体感的に速度が速くなります。
ぱたぱたとアイテムが追加されていく感じ・・・。
既知のネタだけどメモメモ・・・。