Home > Archives > 2008-05

2008-05

AS2で遅くなる書き方を研究しようか

上条さんとこで、AS2でOOPをやると遅くなる可能性があると書いてあって泣いた。

AS3 で動的言語のススメ

AS2 における型の使用は、オーサリング時の ”生産性向上のベストプラクティス” としての位置づけ以上ではないわけです。実際 OOP をまじめに追求するほど AS2 のアプリケーションは遅くなる傾向を持っています。

気になったので、単純なカウントアップでベンチマークをとった。

試したところは以下

  • タイムラインに書くかクラスに書くか
  • 型宣言の有無
  • 処理をfunctionにくるむかどうか

AS2でタイムラインに書く。型宣言はなし

//型宣言なし
var startTime = getTimer();
var trialNum = 100000;
var cnt = 0;

for (var i:Number = 0; i < trialNum; i++) {
	cnt++;
}
benchmark();

function benchmark()
{
	var endTime = getTimer();
	trace("time: " + (endTime - startTime)); 
}
//だいたい228

AS2でタイムラインに書く。型宣言あり・カウントアップは生で書く

//型宣言あり
var startTime:Number = getTimer();
var trialNum:Number = 100000;
var cnt:Number = 0;

for (var i:Number = 0; i < trialNum; i++) {
	cnt++
}

benchmark();

function benchmark()
{
	var endTime:Number = getTimer();
	trace("time: " + (endTime - startTime));
}

//だいたい230

AS2でタイムラインに書く。型宣言あり・カウントアップはfunctionにくるむ

リファクタリングの本やOOPの本を読んでいると、できるだけ細かいfunctionに分けるべきだ、と書いてある。確かにそのほうがやりやすいが、やればやるほど遅くなる気はしていた。

//型宣言あり,function
var startTime:Number = getTimer();
var trialNum:Number = 100000;
var cnt:Number = 0;

for (var i:Number = 0; i < trialNum; i++) {
	countUp();
}

benchmark();

function countUp():Void
{
	cnt++;
}

function benchmark():Void
{
	var endTime:Number = getTimer();
	trace("time: " + (endTime - startTime));
}

//だいたい709

クラスに書く

クラスに書いてみた。やってる中身は上とほとんど一緒。試したのは以下。

  • 型あり
  • 型あり・function
  • 型あり・別クラスstatic function
  • 型あり・別クラスを参照static function 「型あり・別クラスstatic function」は
    for (var i:Number = 0; i < trialNum; i++) {
    	cnt = sandbox.BenchTest.countUp(cnt);
    }

「型あり・別クラスstatic function」は

var test:BenchTest = BenchTest;
for (var i:Number = 0; i < trialNum; i++) {
	cnt = test.countUp(cnt);
}

AS2速度まとめ

型なし型あり型あり・function型あり・別クラスstatic function型あり・別クラスを参照static function
タイムライン228230708455
クラス102101245313227

ループ処理だけでの単純な比較なので、あまりあてにならない。

実際のところどっちが速いのかよくわからん、という結果になった。とりあえず、タイムラインでのfunctionがやたら遅いということがわかった。アクティベーションオブジェクトのせいだろうか。

でも、OOPにのっとってめちゃくちゃ細かく分割すると、遅くなることは事実だろう。わりと、お茶濁しな結果に!

AS3とAS2での差はクラスのメンバにあるかどうかでかなり変わる

AS3では

var point:Point = new Point(x,y)
point.x++;

と書くとめちゃくちゃ早い。メンバ変数であるかどうかがかなりの違いの模様。

これを単なるオブジェクトとして扱うとめちゃんこ遅くなる。ハッシュがどうのこうのらしい。配列はそこそこ早い。 PointとArrayで速度比較

var obj:Object = new Object();
obj.x = 1;
obj.x++;

AS2ではどれをやってもほとんど同じ速度だった。

さっさとAS3に全部移りたいぜ!

//var point:Point = new Point(1, 1);
//var obj:Object = new Object();
//obj.x = 1;
var array:Array = [1];
for (var i:Number = 0; i < trialNum; i++) {
	//point.x++;
	//obj.x++;
	array[0]++;
}
AS2でメンバとかの速度
point.x++;obj.x++;array[0]++;
9493106

いつか使いたかったコードハイライト表示プラグインはpukiwikiプラグインと相性が悪かったので、またいつかにしよう

コードのハイライト表示をしてくれるプラグインを突っ込んだら、pukiwikiプラグインと相性がよくありませんでした。

pukiwikiプラグインとハイライトプラグインは適用箇所をくくることが必要になります。

しかし、以下のような混ぜ混ぜするやりかたは[as]の部分がこのまま出力されるだけでNGでした。
[pukiwiki]
pukiwiki記法
[as]
 public function get unko(food:Food):Feed {
    return _unko;
}
[/as]
[/pukiwiki]
こっちなら動くけど…
[pukiwiki]
pukiwiki記法
[/pukiwiki]
[as]
 public function get unko(food:Food):Feed {
    return _unko;
}
[/as]

これはめんどくさい。pukiwikiやりもって、asに切り替えて…というループ処理は人間には向いてません。

さらに悪いことに、[/pukiwiki]と[as]の区切りの間に空の<p>が紛れるという事態に。もういいや。やーめた!

コードハイライトプラグインの文書は以下がよくまとまっている上にAS3まで対応してはりました。

iG:Syntax HiliterでActionScript 3.0をハイライト

  • Comments (Close): 0
  • Trackbacks (Close): 0

いまさらDelegate.createを理解しようと思ったけれど、謎が深まった愛され系の俺

長らくAS2でお世話になっているおまじない、Delegate.create。ただなんとなしに使うのではなく、そろそろ理解しようと思い調べてみました。

理解するためには2つ必要でした。

  1. argumentsオブジェクトの理解
  2. Functionクラスの理解

argumentsオブジェクトの理解

argumentsオブジェクトは引数オブジェクトのことです。アクセスするには配列演算子を用いますが、単なる配列とは異なるようです。

argumentsオブジェクトにはcallerとcalleeプロパティが存在します。

arguments.caller

現在実行中の関数を呼び出した関数への参照となります。関数オブジェクトはdynamicクラスなので、あとからいくらでもプロパティを追加できるので、実際に参照しているのかテストしてみましょう。

function firstStep(){
	secondStep();
}
firstStep._x = 1;

function secondStep(){
	trace(arguments.caller._x);
	arguments.caller._x++;
}
firstStep();   //1が出力される
firstStep();   //2が出力される
firstStep();   //3が出力される

arguments.callee

現在実行中の関数への参照となります。

Functionクラスの理解

Function.apply()

Function.apply(scope:Object, [argArray: Array ]) :Void

functionオブジェクトのthisを置き換えるのがこのapplyメソッド。 これをうまく使えばmc.onReleaseなどのthisが変わるめんどくささから解放されます。

以上を踏まえて、mx.utils.Delegate.create()では何をしているのかというと

まずはmx.utils.Delegate.create()のコードを見てみましょう。

static function create(obj:Object, func:Function):Function
{
	var f = function()
	{
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		return func.apply(target, arguments);
	};

	f.target = obj;
	f.func = func;
	return f;
}
  1. functionオブジェクト(var f)を作成
  2. functionオブジェクトに匿名関数を参照させる
  3. functionオブジェクトはdynamicクラスなので、追加プロパティを作れる
    • scopeとなるobjectと関数を保持させる
  4. 匿名関数内で、arguments.calleeを使って、自身(現在の関数)を参照し、
    • 先ほど保持したscopeと関数を拾う。
    • func.apply()で意図したscopeにfuncを割り当てる(thisを変える)

だいたいこんな感じでした。しかしながら、func.apply()には同時に引数も渡せるはずです。なので、ちょっと付け足してみました。

static function createWithArgs(obj:Object, func:Function, args:Array):Function
{
	var f = function()
	{
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		return func.apply(target, arguments.callee.args.concat()); //ここを追加
	};

	f.target = obj;
	f.func = func;
	f.args = args; //ここを追加
	return f;
}

applyメソッドの第2引数にarguments.callee.args.concat()を追加するとうまく引数を登録できます。 引数の配列となるargsはconcatしないとうまく動作しません。

このあたりがさっぱりわからなかったので、ググってみましたがめぼしいものは見つからずさらに謎の動作まで見つけてしまいました。

http://library.sfug.ch/trac/browser/trunk/doc/as2/examples/sfug_as2lib/ch/sfug/utils/Delegate.as

ここはarguments.shift()でscopeとfuncを定義してるあたりがおもしろいですね。concat(arguments)でさらにdelegateした後で呼び出したときの引数も定義しています。なぜargumentsが使えるのかがなんとなくでしかわからないので、完全なる理解にはしばらく時間がかかりそうです。

新しい会社に移りました。

4月末で前職を退職し、5月より新しい会社で働くことになりました。Flashやる人です。

まだ2週間しか働いてませんが、かなりカルチャーショックです。いままでの底辺付近のヤバいやり方とぜんぜん違います。めちゃくちゃクオリティを求められますし、会社全体の空気がそうなってます

これからじっくり腰をすえてがんばろうと思います。本当にがんばってますよ!まだunkoって1回しか言ってないからね!

そんなunkoちゃんの僕は、すぐunkoに逃げてしまうので、ToDoとNotToDoリストを書いておこう。

さっさとやらないといけないリスト

上から優先度高い

  1. 早寝早起き
  2. motionグラフィックの基礎・引き出し増やす
  3. as3
  4. デザインパターン
  5. CoreserverでSubversion
  6. blogをFlashのことだけ書く
  7. asライブラリを作って公開
  8. プログラミングのノウハウ的なこと・UMLとかそのへんの周辺知識
  9. お笑い(いつも思いつきやから、クオリティとか緩急とかつけたい)
  10. ui
  11. Design

(できれば)やらないリスト。ある意味、そのうちやりたいことリスト

  • 正規表現
  • ruby・php・sqlとかサーバサイド
  • ruby on railsとかのフレームワーク
  • Processing(しまった。今日amazonで本買うてもうた)
  • IA
  • PM(これも本買ってもうた)
  • ファミコン
  • HTML
  • Comments (Close): 0
  • Trackbacks (Close): 0

WordPressでPukiWIKI記法を使いたい!そんな貴女の希望をかなえるのが、このplugin!

pukiwiki記法でblogが書けたら、ずいぶんはやく書けるし、自分用メモからの転載もはかどるのでplugin入れてみました。

おおまかな流れ

  1. Xoopsのpluginを拝借
  2. WordPress用PukiWIKI pluginを設定
  3. 全部utf-8(BOMなし)で保存しなおす
  4. 細かい設定

1~2のおおまかなところはこちらが参考になるので割愛します。 http://blog.absolute-zero.info/?p=88

全部utf-8(BOMなし)で保存しなおす

  1. アップロードしたファイルすべてをUTF-8(BOMなし)に保存しなおします。
  2. modPukiWiki/PukiWiki.phpの8行目を以下に変更
    if (!defined('MOD_PUKI_SOURCE_ENCODING')) define('MOD_PUKI_SOURCE_ENCODING','UTF-8');

こまかいところ

ulなどに勝手につくstyle属性をなくす設定

ulの入れ子をしたりすると、かなりstyle属性を入れられるので、消す。かなり物量が多いので、簡単なところだけ消しときます。(ホンマはmarginの計算処理部分も消したいけど、多くて断念)

config/default.php

  • 80行目
  • style="~~と書かれているとこを消す
    • これを
      $_settings['_list_pad_str'] = ' class="'.$_settings['style_prefix'].'list%d" style="padding-left:%dpx;margin-left:%dpx"';
    • これに変更
      $_settings['_list_pad_str'] = "";

一応、勝手に付与されるmargin、paddinの値も0にしとく

class/PukiWikiElement.php

  • 263行目付近のclass PukiWikiListContainerのfunction PukiWikiListContainerを変更
    • これを
      $this->margin = PukiWikiConfig::getParam($var_margin);
      $this->left_margin = PukiWikiConfig::getParam($var_left_margin);
    • 以下のようにmarginとpaddingの値を0に変更する
      $this->margin = "";
      $this->left_margin = "";

h1は使わないので、一つずつ見出しレベルを下げる

  • 「*」はh1じゃなくて、h2になってほしいので変更する

class/PukiWikiElement.php

  • headingまわりの修正
  • 207行目付近、PukiWikiHeadingのfunction PukiWikiHeadingの中
    • これを
      $this->level  = min(6, strspn($text, '*'));
    • これに変更
      $this->level  = min(6, strspn($text, '*') + 1 );
      

あわせて「#contents」の挙動も変更する

  • ulが2つしか入れ子になってくれないので、変更する
  • さっきheadingでlevelを変更したのでそれを直すのと、ulの入れ子を増やします。

class/PukiWikiElement.php

  • 1188行目付近のfunction Contents_UListに一行追加
    • $level -= 1;
  • 278行目付近のfunction PukiWikiListContainerを変更する
    • これを
      $this->level = min(3, strspn($text, $head));
    • これに変更
      $this->level = min(5, strspn($text, $head));
      

あとアンカーがおかしいことになってるので変更

class/PukiWikiElement.php

  • 1142行目付近のfunction getAnchorを変更
    • これを
      $id = "content_{$this->id}_{$this->count}";
    • これに変更
      $id = "content_{$level}_{$this->count}";

実際に使った感想。

  • h6まで見出しを作れる
  • 入れ子<ul>・<ol>は通常通り3個まで
    • 入れ子<li>の挙動がおかしい。入れ子<li>の中にブロック要素を入れると、そのブロック要素の直前に「</p>」を無理やり生成される
  • #contentsの目次生成は便利だけど、topやrssには不要なので、その辺をどうにかしたい。
    • topに置くと、id名が重複する可能性が高い?どうなんかな。
      • →ひとまずis_single()で個別記事だけ表示するように変更した。
      • 個別記事ID発行のthe_ID()を使ってid名に含ませようとしたが、ぜんぜんうまく動かなかった

しかしながら、これでめっちゃくちゃ楽になるぜ!まあ、wordpress止めてpukiwikiに移行しろとかは言わないでください。

Home > Archives > 2008-05


Search
Feeds
Meta

Return to page top