T

PHPのパフォーマンス改善(3)

Zend / PHP Conference & Expo 2006でのIlia Alshanetsky氏プレゼン資料(PDF)

やや旧聞に属するが、一次保存場所に漂っているファイルを見つけたのでまとめてみた。Apacheやサーバのチューニングも含まれていてなかなか面白かったが、ここではPHPのプログラマがスクリプトを記述する際に注意する点を取り上げる。

(6)その他いろいろ。

■エラーを出力しないオペレータ「@」はコストがかかる

まあ、その通り。

■配列のキーの指定の仕方

$array[foo] = 1;
$array['foo'] = 1;

この2行を比較すると、シングルクォートで明示的に文字列とする方が700%速い。

■文字列比較の比較

最速:

if(!strncmp(PHP_OS, 'WIN', 3)){
if(!strncasecmp(PHP_OS, 'WIN', 3)){

ちょっとダメ

if(substr(PHP_OS, 0, 3) == 'WIN'){
if(strtolower(substr(PHP_OS, 0, 3)) == 'win'){

ぜんぜんダメ

if(preg_match('!^WIN!', PHP_OS)){
if(preg_match('!^WIN!i', PHP_OS)){

最速パターンだと、大文字小文字の区別をしてもしなくてもパフォーマンスに影響がなく、1.5倍くら速い。

そもそもPHP5からはsubstr_cmpare関数があるので、substrを比較で使うことはない。

■無意味なエラー出力をなくす

エラー出力をすると

  • 複雑なエラー出力を生成する
  • 標準出力や標準エラーに出力する
  • ファイルやsyslogに書き出すこともある
  • 5.2以前のリリースではまれにメモリリークする

ため、無闇にエラーを出力しない方がいい。

■forループの評価式の中で関数を使わない

for($i = 0; $i <= strlen($str); $i++){
    // do something
}

これを

$length = strlen($str);
for($i = 0; $i <= $length; $i++){
    // do something
}

これにすることで2〜3倍の速度改善が。

■フルパスの記述はパフォーマンスにやさしい

include_pathを検索するよりはいいよ、ということ。

■多次元配列の処理に参照渡しを使う

$array['foo']['bar'] = array();
for($i = 0; $i <= 5; $i++){
    $array['foo']['bar'][$i] = $i;
}

これよりも

$ref =& $array['foo']['bar'];
for($i = 0; $i <= 5; $i++){
    $ref[$i] = $i;
}

こっちの方がシンプルでわかりやすく、しかも速い。

■最適化にまつわる神話

  1. コメントをなくすと速くなる
  2. ダブルクォート(”)はシングルクォート(’)より速い
  3. 参照渡しの方がコードが速くなる
  4. オブジェクトを使う方が速くなる
  5. タナリ($a = 1 ? $b = $a : $b = 0;)はif(){}else{より速い

これらは全部嘘です。

Posted by on 2月 16, 2007 in PHP

Comments

  • […] PHPのパフォーマンス改善(3) | Selfkleptomaniac (tags: php パフォーマンス) […]

  • […] PHPのパフォーマンス改善(3) | Selfkleptomaniac という記事にstrncmpを含んだ3つの方法が書かれていたので計5つの方法のベンチを取って比較してみた。 (各秒数は約8万行を検索したしたベンチ […]

  • コメントを残す