404 motivation not found | t_ishidaのブログ

Archive for 8月 2011

8月/11

10

create_functionのアレ

PHP5.2以下のPHPを使ってアレしてる人なんか、なんだかんだでcreate_function でアレしたりしてアレするでしょう?

でも、これって調子こいてJavaScriptやLISPのノリや、Perl のサブルーチンのリファレンスのつもりで使ってるとアレしちゃうんですよ。そもそもそこまで便利じゃないので、そのノリで使えないっていうのはアレしちゃってください。で、create_functionをよくアレしてる人は、以下のコード実行してみてください。

for ( $i = 0; $i < 1000000; $i++ ){
  hoge ('$x', 'return $x;' );
}
function hoge ( $x, $y ) { return create_function ( $x, $y ); }

スコープぬけようがcreate_functionした関数は破棄しないし、同じコードだろうが問答無用で新しい関数定義するという男らしい仕様でアレしているので使用可能メモリを一瞬でオーバーして男らしく散り際をわきまえてアレしちゃうんですね。でも、そんなアホみたいな回数をcreate_functionするような場所で回さないもんへへーんとかアレしてる方、

// バッチコントローラの階層
for ( $i = 0; $i < 10; $i++ ) {
  // モデルの階層
  for ( $j = 0; $j < 100; $j++ ) {
    // そのモデルの下請けモデルの階層
    for ( $k = 0; $k < 1000; $k++ ){
      hoge ('$x', 'return $x;' );
    }
  }
}
function hoge ( $x, $y ) { return create_function ( $x, $y ); }

これ位の計算量は普通に有り得るでしょう。うげーやべぇって思ってアレしました? 思ってないなら思った方が良いです。どう考えても思えないなら、ここでは先に進まなくてアレしちゃうので思ってください。

で、こうしてみることにしました。

function create_function_ex ( $args, $code )  {
  return LambdaFactory::create ( $args, $code );
}
class LambdaFactory {
   private static $_Cache = array ();
   public function create ( $args, $code )  {
     if ( !self::$_Cache[$args . "\x0b" . $code]  ) self::$_Cache[$args."\x0b". $code] = create_function ( $args, $code );
     return self::$_Cache[$args . "\x0b" . $code];
   }
}

です。
じゃあ、これと同じファイルに

for ( $i = 0; $i < 10000000; $i++ ){
   $fnc = create_function_ex ( '$x', 'print "$x\n";' );
   $fnc ( $i );
}

を追記して実行してみてください。
PHPさん、ここでは男らしく踏ん張ってくださいましたね。
これで安心してcreate_function 多用した可読性の低いコードを
ハッピーに書けますね!

※勿論、5.3以降のPHPなら create_function なんか使わずに。 function ( $x ) { return $x; } というようにしましょう。

Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Tumblr
  • email
  • Facebook
  • FriendFeed

No tags

Find it!

Theme Design by devolux.org

Tag Cloud