<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>unbland.org blog &#187; Tips</title>
	<atom:link href="http://unbland.org/blog/tag/tips/feed" rel="self" type="application/rss+xml" />
	<link>http://unbland.org/blog</link>
	<description>発見の日々の備忘録。主に Web にまつまる技術ネタ。</description>
	<lastBuildDate>Wed, 18 Nov 2009 03:31:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ActionScript の最適化 Tips を wonderfl に投稿しました</title>
		<link>http://unbland.org/blog/2009/05/17/250.html</link>
		<comments>http://unbland.org/blog/2009/05/17/250.html#comments</comments>
		<pubDate>Sun, 17 May 2009 14:28:06 +0000</pubDate>
		<dc:creator>muta244@admin</dc:creator>
				<category><![CDATA[Flash (ActionScript)]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://unbland.org/blog/?p=250</guid>
		<description><![CDATA[ActionScript の最適化って色々なサイトに載っていますが、wonderfl にまとめて載っておくとコードと動きを同時に確認できるし、自分のためにも便利だと思って色々と投稿しました。コードへのリンクに個人的な私見 [...]]]></description>
			<content:encoded><![CDATA[<p>ActionScript の最適化って色々なサイトに載っていますが、wonderfl にまとめて載っておくとコードと動きを同時に確認できるし、自分のためにも便利だと思って色々と投稿しました。コードへのリンクに個人的な私見を加えてご紹介します。ただ、人によって意見が異なるかもしれないので、コードと動きを直接確認しておくことをお勧めします。この処理はおかしいんじゃないか？とかありましたらコメントください。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/49f45692cecb031be5f851a5fb138c780896cf9b" target="_blank">変数名の長さによる処理速度の違い</a></strong></p>
<p>変数名の長さによる違いはありません。ですので変数名は、他の人が見やすい・自分が後で確認しても分かり易いような名前を付けておいた方が良いです。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/1609eff6ec801f5674c69ef5178a8a72f5de6766" target="_blank">変数を参照する際の処理速度の違い</a></strong></p>
<p>上のコードでは _getPi <<< Math.PI <<< MyMath.PI = Main.PI < PI = _pi = ns::_pi = pi という結果で、ビルトインクラスのプロパティアクセスは若干重いので、ループ内で大量に参照する場合は変数に格納しておく方が良いです。また、getter アクセスの実態は関数ですので結構重いみたいです。MyMath.PI や Main.PI は、他の参照方法に比べると一階層下がるので若干重いですが、100 万回もループしての結果なので、あまり気にする必要はないんじゃないかと思います。ただ、注意事項が一つありますので「色々な整数化手段での処理速度の違い」も目を通しておいて下さい。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/58b9fe83203fb49db603a1df15f39c6692219fdb" target="_blank">if &#8230; else と switch での処理速度の違い</a></strong></p>
<p>if &#8230; else 文は比較回数が少ない場合は軽いですが、比較回数が増えると switch 文の方が高速です。ただ、100 万回も処理させて数ミリ秒の違いですので、臨機応変に見やすい方を記述しておけば良いんじゃないかと思います。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/2948ee85b515eec960753d311b1f9a6856d90474" target="_blank">色々な整数化手段での処理速度の違い</a></strong></p>
<p>Math.floor() が重いのは周知の事実。ただ、ローカル変数に格納したもので計算した場合は軽くなりそうなものの、逆に重くなるというのは以外だったと思います。これは先の「変数を参照する際の処理速度の違い」で Math.PI のようなプロパティを変数に格納しておく Tips と反して、ビルトインクラスのメソッドは逆に負担になりますので注意が必要です。そして本題の整数化では、n >> 0 などのビット演算で整数化する方が多いのですが、int(n) の方が高速だし見やすいのでお勧めです。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/38488a88c1ecdfb66503b05c486106284bd1d39b" target="_blank">Array, Vector 走査時のイテレーション方法による処理速度の違い</a></strong></p>
<p>forEach は関数を実行するコストが掛かるのでやはり重いです。ただ、for each よりも for の方が高速なのは自分的にもビックリでした。倍速近い差が出るので、大量な処理の中で走査処理が必要な場合は for の方が良いかもしれません。もちろん、Array より Vector の方が高速です。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/167a46753bdeff961d8a7c714df0b47c2aedda98" target="_blank">Array, Vector 走査時に加算を行う際の処理速度の違い</a></strong></p>
<p>これももちろん、Array より Vector の方が高速という結果に。ただ、Vector の長さを固定している方が高速になるかと思いきや、固定していなくても参照速度に差はないようです。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/758263b96e8f2724f709020d1e561d43aad7d64a" target="_blank">オブジェクト生成による処理速度の違い</a></strong></p>
<p>new Object() より {}、new Array() より [] が高速というのは周知だと思います。あと、Vector の長さを指定すると最初に要素の初期化処理が入るようで、生成コストが高くなります。あとは Sprite の生成コストは当たり前のように高いです。独自クラスの生成は、処理が少なければ Object を生成するのとあまり変わりません。</p>
<p><strong><a href="http://wonderfl.kayac.com/code/6081e568795e00272a7da8c716e54341b478c009" target="_blank">サイン・コサインの取得方法による処理速度の違い</a></strong></p>
<p>予めサインテーブルを生成した後、ラジアンをテーブルのインデックスに変換して近似値を参照するというもの。かなりの高速化が期待できますが、取得できる値は近似値だという点に注意が必要です。3D での頂点処理などで大量のループ処理を行う際などに効果が期待できるかと思います。</p>
<p>今のところ試したコードはこんな感じです。これからも、他の最適化を思い付いたら wonderfl に投稿した後、ブログにエントリーしていきます。</p>
]]></content:encoded>
			<wfw:commentRss>http://unbland.org/blog/2009/05/17/250.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[Flash Player 10 #4]  PixelBender のファイルを使わずにカスタムフィルターを定義</title>
		<link>http://unbland.org/blog/2008/05/20/24.html</link>
		<comments>http://unbland.org/blog/2008/05/20/24.html#comments</comments>
		<pubDate>Mon, 19 May 2008 15:46:04 +0000</pubDate>
		<dc:creator>muta244@admin</dc:creator>
				<category><![CDATA[Flash (ActionScript)]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Player 10]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://unbland.net/blog/archives/2008/05/flash-player-10-4-pixelbender-%e3%81%ae%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92%e4%bd%bf%e3%82%8f%e3%81%9a%e3%81%ab%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e3%83%95%e3%82%a3%e3%83%ab%e3%82%bf.html</guid>
		<description><![CDATA[すっかり FlashPlayer 10 の魅力に取り付かれています。
&#8216;08.10.09 追記：
CS4 からはメタデータを使ってファイルの埋め込みができるようになるようなので、こんな面倒臭いことしなくても大 [...]]]></description>
			<content:encoded><![CDATA[<p>すっかり FlashPlayer 10 の魅力に取り付かれています。</p>
<p><strong>&#8216;08.10.09 追記：</strong><br />
CS4 からはメタデータを使ってファイルの埋め込みができるようになるようなので、こんな面倒臭いことしなくても大丈夫です。</p>
<p>通常、Shader を使用するときは pbj 形式のファイルが必要ですが、今回はこのファイルを使用せずにカスタムフィルターを作成するという試み。結果から言うと大成功でした。これで他の BitmapFilter 同様、import するだけでカスタムフィルターが使用できます。このやり方は流行ると思うなぁ。Adobe の人もこういう使い方を想定しているんでしょう、きっと。</p>
<p>まずはカスタムフィルターのコード。</p>
<pre class="as3" name="code">package
{
    import flash.display.Shader;
    import flash.filters.ShaderFilter;
    import flash.utils.ByteArray;

    public class ColorizeFilter extends ShaderFilter
    {
        // ここが重要！
        // あらかじめ、PixelBender のバイナリデータをベクター情報として格納しておく。
        private static var _data:Vector.&lt;int&gt; = Vector.&lt;int&gt;([-91,1,0,0,0,-92,11,0,67,111,108,111,114,70,105,108,116,101,114,-96,12,110,97,109,101,115,112,97,99,101,0,109,117,116,97,0,-96,12,118,101,110,100,111,114,0,109,117,116,97,0,-96,8,118,101,114,115,105,111,110,0,1,0,-96,12,100,101,115,99,114,105,112,116,105,111,110,0,84,104,105,115,32,102,105,108,116,101,114,32,70,105,108,108,32,99,111,108,111,114,46,0,-95,1,2,0,0,12,95,79,117,116,67,111,111,114,100,0,-95,1,4,1,0,15,99,111,108,111,114,0,-94,4,100,101,102,97,117,108,116,86,97,108,117,101,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-128,0,0,-94,12,100,101,115,99,114,105,112,116,105,111,110,0,99,111,108,111,114,0,-93,0,4,115,114,99,0,-95,2,4,2,0,15,100,115,116,0,48,3,0,-15,0,0,16,0,29,4,0,-13,3,0,27,0,1,4,0,-13,1,0,27,0,29,2,0,-13,4,0,27,0]);
        private static var _byteCode:ByteArray;

        private var _color:uint;

        public function ColorizeFilter(color:uint):void
        {
            // ムービーを通して初めての new 時のみ、Vector を ByteArray に変換する。
            if (_byteCode == null)
            {
                _byteCode = new ByteArray();

                for (var i:int = 0, l:int = _data.length; i &lt; l; i++)
                {
                    _byteCode.writeByte(_data[i]);
                }
            }

            super(new Shader(_byteCode));

            this.color = color;
        }

        public function get color():uint
        {
            return _color;
        }

        public function set color(value:uint):void
        {
            _color = value;
            // プロパティのセッター内で Shader にデータを渡す。
            shader.data.color.value = [value &gt;&gt; 16, value &gt;&gt; 8 &amp; 0xFF, value &amp; 0xFF];
        }
    }
}</pre>
<p>実際に使用するときのコード。</p>
<pre class="as3" name="code">var data:BitmapData = Bitmap(new image()).bitmapData;

data.applyFilter(
    data,
    data.rect,
    new Point(),
    new ColorizeFilter(0xFF0000)
);

addChild(new Bitmap(data));</pre>
<p>こんな感じで通常のフィルターと同じように import して new するだけで使用できます。今回のコード一式も例のごとく libspark に上げてますので、必要な方は http://www.libspark.org/svn/as3/Astro/ShaderFilter/CustomFilter/ 以下をチェックアウトしてください。</p>
]]></content:encoded>
			<wfw:commentRss>http://unbland.org/blog/2008/05/20/24.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Flash Player 10 #3]  Shader + Vector で計算の高速化</title>
		<link>http://unbland.org/blog/2008/05/19/23.html</link>
		<comments>http://unbland.org/blog/2008/05/19/23.html#comments</comments>
		<pubDate>Mon, 19 May 2008 11:49:54 +0000</pubDate>
		<dc:creator>muta244@admin</dc:creator>
				<category><![CDATA[Flash (ActionScript)]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Player 10]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://unbland.net/blog/archives/2008/05/flash-player-10-3-shader-vector-%e3%81%a7%e8%a8%88%e7%ae%97%e3%81%ae%e9%ab%98%e9%80%9f%e5%8c%96.html</guid>
		<description><![CDATA[beinteractive さんの twitter でのコメント。
Player10 で結構な長さのint配列に対して演算をしなければならない場合、
1. ただのArray
2. Vector.&#60;int&#62;
3 [...]]]></description>
			<content:encoded><![CDATA[<p>beinteractive さんの twitter でのコメント。</p>
<p>Player10 で結構な長さのint配列に対して演算をしなければならない場合、<br />
1. ただのArray<br />
2. Vector.&lt;int&gt;<br />
3. Vector.&lt;int&gt; を BitmapData に setVector して、Shader (Pixel Bender) で計算後、 getVector<br />
のどれが一番速いんだろう</p>
<p>を受けて、自分も気になったので調べてみました。100 万個強のデータに uint を加算するテスト結果は以下の通り。</p>
<p>Array =&gt; 361 ms<br />
Vector =&gt; 188 ms<br />
Shader + Vector =&gt; 35 ms</p>
<p>Shader + Vector の組み合わせは Array より十倍近く早い結果に。今回は簡単な加算のみですが、色々と試してみる価値がありそうですね。<a href="http://www.libspark.org/browser/as3/Astro/ShaderFilter/CalcShader/src/CalcShader.as">試したコード</a>は libspark に上げています。一式必要な方は http://www.libspark.org/svn/as3/Astro/ShaderFilter/CalcShader/ 以下をチェックアウトしてください。</p>
<p><b>&#8216;08 5/23 追記：</b><br />
活用法がないか色々と考えたり試したりしているんですが、そもそも setVector する時点で 0&#215;00FFFFFF 以下のデータはアルファが 0 になるので、数値自体も 0 としてセットされてしまうんですよね。PixelBender 上で一ピクセルの情報だけを取り出して・・・とかの方法も分からない（できない？）し、何か良い活用法思いついた方はいらっしゃらないでしょうか？</p>
]]></content:encoded>
			<wfw:commentRss>http://unbland.org/blog/2008/05/19/23.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ActionScript 3 のフィルターについて。</title>
		<link>http://unbland.org/blog/2008/04/09/20.html</link>
		<comments>http://unbland.org/blog/2008/04/09/20.html#comments</comments>
		<pubDate>Tue, 08 Apr 2008 16:19:17 +0000</pubDate>
		<dc:creator>muta244@admin</dc:creator>
				<category><![CDATA[Flash (ActionScript)]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://unbland.net/blog/archives/2008/04/actionscript-3-%e3%81%ae%e3%83%95%e3%82%a3%e3%83%ab%e3%82%bf%e3%83%bc%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6%e3%80%82.html</guid>
		<description><![CDATA[以前、HiSprite クラスという、フィルター関連の設定をプロパティで行えるようにしたクラスを作成しました。ただ、これだと Sprite を継承した独自クラスなどに適用できません。ですので、この場合は委譲用クラスを実装 [...]]]></description>
			<content:encoded><![CDATA[<p>以前、<a href="http://www.libspark.org/browser/as3/Unbland/src/net/unbland/display/HiSprite.as" target="_blank">HiSprite</a> クラスという、フィルター関連の設定をプロパティで行えるようにしたクラスを作成しました。ただ、これだと Sprite を継承した独自クラスなどに適用できません。ですので、この場合は委譲用クラスを実装した方が実用的だと考えました。しかし、ことごとく壁にぶち当たり、結論から言うと断念。</p>
<p>そんなこんなを twitter で愚痴っていると、<a href="http://logi.nium.jp/" target="_blank">nium</a> 先生と <a href="http://www.be-interactive.org/" target="_blank">beinteractive</a> 先生からアドバイスを頂きました。<a href="http://twitter.com/nium/statuses/785120161" target="_blank">「元オブジェクトに触られた場合に整合性を取ることは委譲の永遠の課題」というコメント</a>などはとても参考になり、ありがたかったです。この場を借りてお礼申し上げます。両先生、ありがとうございました！</p>
<p>以下、色々試してみたメモ。<br />
<u><strong>3.</strong></u> 辺りはまだ望みがありそうなので、今後も試してみる予定です。</p>
<p><span id="more-20"></span><br />
<u><strong>1. 委譲元の filters プロパティから適用済みのフィルターを判別して実装。</strong></u></p>
<p>適用済みのフィルターを判別する際に問題が発生。filters プロパティは getter 内で中身のフィルターまで clone() しちゃってる模様。以下、検証用コード。</p>
<pre name="code" class="as3">package
{
    import flash.display.Sprite;
    import flash.filters.BlurFilter;

    public class Document extends Sprite
    {
        public function Document ():void
        {
            var blur:BlurFilter = new BlurFilter();
            filters = [blur];

            trace("trace :", filters[0], filters[0]);
            // trace : [object BlurFilter] [object BlurFilter]

            trace("trace :", filters[0] == filters[0]);
            // trace : false
        }
    }
}
</pre>
<p>描画処理のために配列を直接操作されたくないのだとは思うのですが、それならば setter 内で clone() して処理しててくれればよかったのに・・・と思うわけで。そこで、試しにもう一つ検証用コード。</p>
<pre name="code" class="as3">package
{
    import flash.display.Sprite;
    import flash.filters.BlurFilter;

    public class Document extends Sprite
    {
        public function Document ():void
        {
            var blur:BlurFilter = new BlurFilter();
            blur.blurX = 10;
            filters = [blur];
            blur.blurX = 100;

            trace("trace :", filters[0].blurX);
            // trace : 10
        }
    }
}
</pre>
<p>setter 内でもしっかり clone() されているみたいですね。描画処理のために、こればっかりはしょうがないんだなぁ、きっと。</p>
<p><u><strong>2. 委譲用クラスのために BitmapFilter 系クラスを継承したクラスを独自実装。</strong></u></p>
<p>独自実装するフィルタークラスは internal なり独自のネームスペースなりでかくまっておいて、 clone メソッドをオーバーライドして自分自身を返すようにしてしまおうと試みたのですが、そもそも BitmapFilter 系クラスは final されてて継承できませんでした。わぉ、盲点。</p>
<p><u><strong>3. Proxy クラスで委譲用クラスのためのフィルタークラスを実装。</strong></u></p>
<p>と思ったらすでに<a href="http://d.hatena.ne.jp/seagirl/20080205/1202146520" target="_blank">試されている</a>方がいらっしゃいました。しかし、filters は setter 内でクラス判別を行っているため、結局は駄目な模様。</p>
<p><u><strong>4. 委譲元の filters プロパティの奥地に委譲用のフィルターを格納。</strong></u></p>
<p>これも失敗。以下、検証用コード。</p>
<pre name="code" class="as3">package
{
    import flash.display.Sprite;
    import flash.filters.BlurFilter;

    public class Document extends Sprite
    {
        public function Document ():void
        {
            var blur:BlurFilter = new BlurFilter();
            var array:Array = [];

            // これは代入しても大丈夫。
            //array[0] = array;

            // これは代入すると Error がスローされる。
            array[100] = array;

            filters = array;
        }
    }
}
</pre>
<p>filters プロパティに代入する配列は綺麗に 0 から格納されてないと駄目でした。</p>
]]></content:encoded>
			<wfw:commentRss>http://unbland.org/blog/2008/04/09/20.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.444 seconds -->
