2012年8月23日木曜日

php高速化tips

勉強になったのでメモ。


 *  PHP コード最適化 Best Practices 63+
  * 01. static にできるメソッドは static として宣言しよう。(4倍速い)
  * 02. echo の方が print より速い。
  * 03. echo '文','字'; (カンマ区切り)の方が、'文'.'字' (ドット連結)より速い。
  * 04. ループの最大値は、ループ「内」ではなく「前」にセットしておこう。
  * 05. 大きい配列のような変数は unset() してメモリを解放しよう。
  * 06. マジックメソッド(例: !__get, !__set, !__autoload)は使用を避けよう。
  * 07. require_once はハイコストなのです。
  * 08. include や require でファイルはフルパスで指定しよう。
  * 09. スクリプト開始時間は time() でなく $_SERVER!['REQUEST_TIME'] で取得。
  * 10. 可能であれば、正規表現より strncasecmp、strpbrk、stripos を使おう。
  * 11. strtr(str_replace の4倍速い) > str_replace > preg_replace の順に速い。
  * 12. 引数に配列、文字列両方を受け入れるような関数は避け、個別に関数化しよう。
  * 13. if をたくさん使ってるなら switch を活用しよう。(訳注:ってことでいい?)
  * 14. @によるエラー制御はすんごく遅い。
  * 15. Apache の mod_deflate(Apache2系) を ON にしておこう。(No.42 参照)
  * 16. 処理が終わったらデータベースの接続は切っておこう。
  * 17. $row!['id'] は $row[id] より7倍速い。
  * 18. エラーメッセージはハイコスト。
  * 19. for 文の条件式には count($array) のような関数をいれない。(変数に格納)
  * 20. メソッド内ではローカル変数をインクリメントするのが一番速い。
  * 21. グローバル変数のインクリメントはローカル変数より2倍遅い。
  * 22. オブジェクト変数(例:$this->v++)のインクリメントはローカルより3倍遅い。
  * 23. 未定義のローカル変数のインクリメントは定義されたものより9~10倍遅い。
  * 24. 未定義のグローバル変数についても同様。
  * 25. メソッドの起動コストはクラス内のメソッド数とは無関係。
  * 26. 派生クラス内のメソッドは、基底クラスで定義されたメソッドよりも速い。
  * 27. 引数1つの空関数を呼び出すのにも、ローカル変数 $local++ 7~8回分のコスト。
  * 28. ダブルクォート より シングルクォート の方が若干速い。
  * 29. 03 と重複か。(注:これは複数の引数を受け取る echo でのみ有効)
  * 30. PHP スクリプトは静的な HTML ページよりも2~10倍の時間がかかる。
  * 31. キャッシュを利用しよう。通常、コンパイル回数 x 25~100% 分速くなる。
  * 32. これもキャッシュについて。memcached とか使おうよ。
  * 33. if (strlen($foo) < 5) を調べたいなら if (!isset($foo!{5})) と書くと速い。
  * 34. $i++ より ++$i の方が速い。(そういう opcode optimizer が走ってる場合)
  * 35. 全部が全部 OOP でなくても良い。(コストやメモリの浪費になってるかも)
  * 36. すべてのデータをクラスにしようとしないこと。配列も十分便利です。
  * 37. メソッドを分割しすぎない。(どれを再利用するのかよく考えよう)
  * 38. メソッドを分割したくなったら後でいくらでもできる。
  * 39. もとから用意されてる 関数たち を活用しよう。
  * 40. 非常に時間のかかる関数 → C言語による拡張モジュール化も検討しよう。
  * 41. コードをプロファイリングしてボトルネックを見つけよう。Xdebug とか。
  * 42. Apache の mod_gzip(Apache 1系)は、転送量を最大80%減。
  * 43. : A HOWTO on Optimizing PHP with tips and methodologies を見てね。
  * 44. 28 と重複か。
  * 45. 13 と重複か。
  * 46. 19 と重複か。
  * 47. ループ処理には foreach を使おう。
  * 48. 複雑なクラスを作ってるなぁと思ったら → Singleton モデルを検討しよう。
  * 49. DB に入れる値なら GET より POST を使おう。(パフォーマンスが上がる)
  * 50. 可能なら正規表現より、ctype_alnum、ctype_alpha、ctype_digit を使おう。
  * 51. ファイル指定は basename / file_exists / open_basedir よりフルパス指定が速い。
  * 52. require_once より require を使おう。(opcode キャッシュがらみの理由で)
  * 53. 一時的なファイルを作るときには tmpfile や tempnam を使おう。
  * 54. 外部サービスに XMLHTTP で接続するときにはエラー回避のため Proxy を使おう。
  * 55. デバッグするときは error_reporting (E_ALL); にしておこう。
  * 56. Apache の allowoverride を "none" にしておくとパフォーマンスが向上。
  * 57. 静的なコンテンツには thttpd のような高速なファイルサーバを使おう。
  * 58. パスなどの設定パラメータは配列に serialize して入れ、キャッシュしておこう。
  * 59. アクセスの多いページには PHP の 出力バッファリング を使おう。
  * 60. DB 固有の prepare メソッドではなく PDO::prepare を使おう。
  * 61. SELECT * (ワイルドカード)を使うのはやめよう。
  * 62. PHP より賢い DB ロジック(queries, joins, views, procedures)を活用しよう。
  * 63. SQL の省略表記を活用しよう。
   * (例:INSERT INTO MYTABLE (FIELD1,FIELD2) VALUES (("x","y"),("p","q"));)

 * [ PHPコード最適化Tipsのウソと本当(解説)] (PHP コード最適化 Best Practices 63+に優先度と解説つけたもの)
  * 優先度A. 頻度も高いし使えそう
   * 01. static にできるメソッドは static として宣言しよう。(4倍速い)
   * クラス内で定数代わりに使ってる変数があるなら、const にしよう。
   * 04. ループの最大値は、ループ「内」ではなく「前」にセットしておこう。
   * 19. for 文の条件式には count($array) のような関数をいれない。(変数に格納)
   * 10. 可能であれば、正規表現より strncasecmp、strpbrk、stripos を使おう。
   * 11. strtr(str_replace の4倍速い) > str_replace > preg_replace の順に速い。
   * 50. 可能なら正規表現より、ctype_alnum、ctype_alpha、ctype_digit を使おう。
   * 39. もとから用意されてる 関数たち を活用しよう。
   * 53. 一時的なファイルを作るときには tmpfile や tempnam を使おう。
   * 18. エラーメッセージはハイコスト。
   * 55. デバッグするときは error_reporting (E_ALL); にしておこう。
   * 17. $row!['id'] は $row[id] より7倍速い。
   * 23. 未定義のローカル変数のインクリメントは定義されたものより9~10倍遅い。
   * 24. 未定義のグローバル変数についても同様。
   * 31. キャッシュを利用しよう。通常、コンパイル回数 x 25~100% 分速くなる。
   * 32. これもキャッシュについて。memcached とか使おうよ。
   * 58. パスなどの設定パラメータは配列に serialize して入れ、キャッシュしておこう。
  * 優先度B. 機会があれば / 迷ったら使うかな的
   * 03. echo '文','字'; (カンマ区切り)の方が、'文'.'字' (ドット連結)より速い。
   * 08. include や require でファイルはフルパスで指定しよう。
   * 51. ファイル指定は basename / file_exists / open_basedir よりフルパス指定が速い。
   * 09. スクリプト開始時間は time() でなく $_SERVER!['REQUEST_TIME'] で取得。
   * 20. メソッド内ではローカル変数をインクリメントするのが一番速い。
   * 21. グローバル変数のインクリメントはローカル変数より2倍遅い。
   * 22. オブジェクト変数(例:$this->v++)のインクリメントはローカルより3倍遅い。
   * 28. ダブルクォート より シングルクォート の方が若干速い。
  * 優先度C. 実はほとんど効果がないけどね
   * 02. echo の方が print より速い。
  * 優先度不明. 効果がいまいちわかんないです。誰か説明 / 検証してください
   * 05. 大きい配列のような変数は unset() してメモリを解放しよう。
   * 07. require_once はハイコストなのです。
   * 52. require_once より require を使おう。(opcode キャッシュがらみの理由で)
   * 16. 処理が終わったらデータベースの接続は切っておこう。
  * 非推奨? 速度の代償が大きすぎるんじゃ…
   * 06. マジックメソッド(例: !__get, !__set, !__autoload)は使用を避けよう。
   * 33. if (strlen($foo) < 5) を調べたいなら if (!isset($foo!{5})) と書くと速い。
   * 34. $i++ より ++$i の方が速い。(そういう opcode optimizer が走ってる場合)