いつか作ります RSSフィード

2009-07-14

[]WEwLC 03:20 WEwLC - いつか作ります を含むブックマーク はてなブックマーク - WEwLC - いつか作ります WEwLC - いつか作ります のブックマークコメント

10,000行オーバーとか言う糞馬鹿でかいクラスにメソッドを追加するようなハメに陥りそうだったので

class UnkClassWrapper{
 function __construct($instance){
  $this->instance = $instance;
 }
 function __call(){
  //丸ごと委譲。めんどいので略
 }
 function __get(){
  //丸ごと委譲。めんどいので略
 }
}

とか書いて、このクラスでメソッドを実装してお茶を濁した。

だいたい、そんなデカいクラスいじってたら、どんだけ更新衝突するか知れたもんじゃねえ。

2009-06-24

[]PHPではガンガン変数を複製してかまわない 21:22 PHPではガンガン変数を複製してかまわない - いつか作ります を含むブックマーク はてなブックマーク - PHPではガンガン変数を複製してかまわない - いつか作ります PHPではガンガン変数を複製してかまわない - いつか作ります のブックマークコメント

期待したのに!

Don't copy variables for no reason. Sometimes PHP novices attempt to make their code "cleaner" by copying predefined variables to variables with shorter names. What this actually results in is doubled memory consumption, and therefore, slow scripts. In the following example, imagine if a malicious user had inserted 512KB worth of characters into a textarea field. This would result in 1MB of memory being used!

BAD: $description = $_POST['description']; echo $description;

GOOD: echo $_POST['description'];

大嘘をこくなクソッタレ。

検証

面倒なので、メモリ使用量は上限で測る。つまり、落ちるか落ちないかだけ見る。

//前提1:これは落ちない

$str1 = str_repeat('1', 30000000);

//前提2:これは落ちる(メモリ不足)

$str1 = str_repeat('1', 30000000);

$str2 = str_repeat('1', 30000000);

という状態になるまで適当に数字をいじる。ここから開始。で、

変数を複製してみる

//これは落ちない

$str1 = str_repeat('1', 30000000);

$str2 = $str1;

googleの主張に拠ればこのコードを実行したら前提2のコードと同じだけメモリを食う、つまり前提1の倍メモリを食うので、落ちなければいけない。のだが、実際は落ちない。ここ、驚くところね。

つまり、PHPでは、変数を別の変数に代入しても、メモリ上では変数は複製されない。

ちなみにこうすると落ちる。

//これは落ちる

$str1 = str_repeat('1', 30000000);

$str2 = $str1;

$str2 = $str2 . '1';

ポインターを示すのが面倒なので結論だけ言うと、PHPは値を複製しても、本当に必要になるまでは値を複製せず、同じメモリ位置を参照し続ける。オリジナルとは別でメモリを確保する事が必要になった時に改めて別の場所にメモリを確保し、値を複製する。

最後の例だと、$str2が更新される時点(3行目)で初めて値が複製される。2行目の時点では30000000文字の文字列はメモリ上に1つしか存在しない。変数を複製しても、2倍のメモリが消費される、という事はない。

ちなみに、関数の引数でも同じ事が起きる。見た目には値渡しと同じように動作するのだが、実際は参照が渡されている。だから、引数に再代入するとかいう野蛮な行為にさえ及ばなければ、関数にはガンガン値渡しをして問題ない。メモリ管理などという低俗な事はC層が勝手にやってくれる。

(厳密にはポインタっぽいものの分や、こういう小賢しい管理をするためにメモリを食うので、変数のコピーがゼロコストというわけではない。が、そんな性能差を気にするようなシチュエーションならそもそもPHPなんぞ使うべきではない)

つうかechoとprintの性能差がどうのとか言ってるし。何ナノ秒の差だよそれ。これだからPHPerはダメだといわれるんだ。

ここにまた新たなPHP伝説が誕生した。

たとえGoogle社員でもPHPerは駄目

追記:

流石にツッコミが入ったらしく、修正が入っている。現在のサンプルならばメモリ消費量が増えるので、指摘自体は正しくなっている。

2009-05-31

[]答えてみる 答えてみる - いつか作ります を含むブックマーク はてなブックマーク - 答えてみる - いつか作ります 答えてみる - いつか作ります のブックマークコメント

なんと2年前だ!w

  1. 配列usersに「john」を追加しないのはどれか?
    • 1と3は追加する。他は知らん。
  2. sort(), assort(), ksort()の違いを述べよ。また、どういった状況で利用するかを述べよ。
    • sort()はキーを無視してソートする。キーは捨てるんだか信用できなくなるんだか。ksort()はキーを維持したままキーの順序でソート。他のソート関数はusort()しか使わないので知らん。つうかリファレンス引けば分かる事を聞くなよ面接で。
  3. 以下のコードは何を出力するか?それはなぜか?
    • 関数スコープとグローバルスコープ。10を出力する。
  4. 参照と通常の変数の違いを述べよ。また、どのように参照渡しをするか、なぜそうするかを述べよ。
    • 参照を変更するとオリジナルが改竄される。参照じゃないのはオリジナルは変化しない。関数にオブジェクトを渡す場合は常に参照。プリミティブや配列は値渡し(に見える)。PHPではメモリ節約のためだけに参照渡しをする必要は一切ない。
  5. 実行中のスクリプトにライブラリコードを追加する関数は何か?
    • require_once()とかその辺のこと?
  6. foo() と @foo()の違いを述べよ。
    • @を使うとエラーを握り潰す事で、プログラムの実行速度を落とすとともにデバッグを困難にできる。
  7. あなたがどのようにPHPアプリをデバッグしているかを述べよ。
    • ささやき いのり えいしょう var_dump()!PHPUnitは灰になった。
  8. 「===」は何をするか? 「==」がtrueを返し「===」がtrueを返さないサンプルを示せ。
    • 1=='1+1'がtrue。
  9. メソッドやプロパティを持たないクラス「myclass」はどのように宣言するかを示せ。
    • class myclass{}
  10. 「myclass」のインスタンスをどうやって生成するかを述べよ。
    • $instance = new myclass();
  11. どうやってクラスのプロパティにアクセスしたり値を設定するかを述べよ。
    • $instance->hoge = $instance->fuga;
  12. includeとinclude_onceの違いを述べよ。また、includeとrequireの違いを述べよ。
    • include系は失敗してもなかった事にする。require系は失敗したら潔く腹を切って死ぬ。onceがつくと同じファイルは高々一回しか読み込まない。
  13. ブラウザに新しいページにリダイレクトさせるための関数は何か?(多肢選択式)
    • header()。
  14. ファイルを読み書きするため、ファイルを「開く」関数どれか?(多肢選択式)
    • fopen()。
  15. mysql_fetch_row()とmysql_fetch_array()の違いを述べよ。
    • どっちもイモ野郎がよく使う。最低でもmysqli_*を使え。もしくはPDO。前者がfetch()で後者がfetchAll()だっけ?
  16. 以下のコードは何をするか?起こっていることを説明せよ。
    • $date=’08/26/2003’;
    • print ereg_replace(“([0-9]+)/([0-9]+)/([0-9]+)”,\\2/\\1/\\3,$date);
      • 26/08/2003。後方参照っつうんだっけコレ。
  17. $stringにテキストが代入されているとき、HTMLタグを全て除去する正規表現はどのように書けば良いか?
    • そんなものを自前で実装すると < < br > script > とかを取り逃すに決まってるのでstrip_tag()だかそんな感じの関数を使えってけーねが言ってた。
  18. PHPとPerlにおいて、配列とハッシュの扱い方の違いを述べよ。
    • PHPに配列は存在しない。PHPのハッシュは順序を覚えてくれる便利な子だが、Rubyにも搭載されるとか聞いた。PHPの配列リテラルはダサい。
  19. HTTPのステートレスな性質を避ける方法を述べよ。
    • セッション?
  20. GDライブラリは何をするかを述べよ。
    • getimagesize()の結果を配列で返すことで、毎回毎回「あれ、widthとheightどっちが先だっけ?」と人を不愉快にさせる。
  21. HTMLコードブロックを出力するいくつかの例を挙げよ。
    • < html > < /html >
  22. PHPはPerlより優れているか、論じよ。
    • ドイツ製戦車は単体性能こそ高かったが、取り扱いの容易な連合戦車による物量作戦で敗北を喫する事になったとか何とか。

新着エントリは上に追加。コメントは「はてなユーザのみ」、公開設定はパブリック (だれでも閲覧ができます)。