最近あちこちで見る「PHPコードの最適化」。
ちと興味があったので、純粋に私的な考察。別に間違っても「これが正解」とかでは全然有り得ないので、斜めに軽く読み流してくんなまし。
とりあえず、きれいにList Upされている
http://d.hatena.ne.jp/koto2/20080518/1211070116
を参照させていただきつつ。
- echo の方が print より速い。
printfだと「めっさ重そう」ではあるんだけど。echoとprintって何が違うんだろ?
- echo '文','字'; (カンマ区切り)の方が、'文'.'字' (ドット連結)より速い。
何となく内部実装の想像が付くなぁ。「単純な、可変長引数」の処理と比較して「文字列のadd」の方が処理的に重いんでしょ?
- ループの最大値は、ループ「内」ではなく「前」にセットしておこう。
当然以前ちゃうん?
- 大きい配列のような変数は unset() してメモリを解放しよう。
えと…GCは改良されたと見なしてよいのでせうか?
- マジックメソッド(例: __get, __set, __autoload)は使用を避けよう。
最適化とは違う理由で絶対使わないからいいやw
- require_once はハイコストなのです。
include_onceでもいいんだけど…でもちとエラー処理その他がねぇ。
- include や require でファイルはフルパスで指定しよう。
メンテナンス性能落ちるから絶対にいや。
- スクリプト開始時間は time() でなく $_SERVER['REQUEST_TIME'] で取得。
…ンなもんがあったんだ。とはいえ…「Script開始時間」って何に使うん? ああログとか?
- 可能であれば、正規表現より strncasecmp、strpbrk、stripos を使おう。
正規表現なんて「贅沢品」つかっちゃいけませんw
- strtr(str_replace の4倍速い) > str_replace > preg_replace の順に速い。
とりあえずpreg_replaceは有り得ない選択肢でしょ。
- 引数に配列、文字列両方を受け入れるような関数は避け、個別に関数化しよう。
んと微妙(苦笑
OOP的に「多態性の一つとして」お便利な方向性ではあるし。
- if をたくさん使ってるなら switch を活用しよう。(訳注:ってことでいい?)
Cの頃だと概ね常識だったように記憶してるですが。PHPのロジックはちゃんと見てないなぁ。
ただ。switch使うと2a問題が出てくるからなぁ orz
- @によるエラー制御はすんごく遅い。
「すんごく」の定義にもよるんだけど。「乱用はよくないけどそこまで気にしなくていい」レベルなんじゃないかなぁとか個人的には。
- Apache の mod_deflate(Apache2系) を ON にしておこう。(No.42 参照)
「PHPの最適化」とは全然違う話のような orz
- 処理が終わったらデータベースの接続は切っておこう。
あちこちで色々な異論が聞こえそうだw
まぁ。「接続を永続化できる環境下以外」ではYesだと思う。
- $row['id'] は $row[id] より7倍速い。
っつか後者の書き方ってシンタックスエラーにしてよいのでは?
- エラーメッセージはハイコスト。
…よくわからにゃい。そも「エラーメッセージ」ってどれを指してるんだろ?
- for 文の条件式には count($array) のような関数をいれない。(変数に格納)
当然。
- メソッド内ではローカル変数をインクリメントするのが一番速い。
これも大体予想範囲内。っていうかローカル変数「以外」って何使う気でいたの?
- グローバル変数のインクリメントはローカル変数より2倍遅い。
そもglobalってモノを否定しているので以下略。
- オブジェクト変数(例:$this->v++)のインクリメントはローカルより3倍遅い。
代替え手段ないしねぇ…
- 未定義のローカル変数のインクリメントは定義されたものより9〜10倍遅い。
っつか未定義で使うな。
- 未定義のグローバル変数についても同様。
未定義な上にglobalだなんて以下略。
- メソッドの起動コストはクラス内のメソッド数とは無関係。
完全に無関係なのかなぁ? まぁ線形検索でごにょごにょしてるとも思えないしそんなもんなんだろうけど。
- 派生クラス内のメソッドは、基底クラスで定義されたメソッドよりも速い。
まぁどこに行っても一緒なのではないかと。だからといってこれを基準にちゅーにんぐされてもたまらんが。
- 引数1つの空関数を呼び出すのにも、ローカル変数 $local++ 7〜8回分のコスト。
んと…豆知識?
- ダブルクォート より シングルクォート の方が若干速い。
そりゃ当然だろ。「うにゅ?」思ったひと。"\n"と'\n'との処理の違いに思いを馳せてみてください。
んと…httpd如何にもよりそうなネタ。
- キャッシュを利用しよう。通常、コンパイル回数 x 25〜100% 分速くなる。
でもキャッシュは諸刃なので使うときは色々注意。
- これもキャッシュについて。memcached とか使おうよ。
ある程度以上ヘビーなサーバ扱うと。ど〜しても「メモリがネックになる」事が多くて…どうしてもmemcachedに肯定的なイメージが持ちにくい orz
- if (strlen($foo) < 5) を調べたいなら if (!isset($foo{5})) と書くと速い。
微妙だなぁ。Tipsとして面白いけど、コメントに書いておかないと混乱を招きそう。
- $i++ より ++$i の方が速い。(そういう opcode optimizer が走ってる場合)
ど〜ゆ〜optimizer?
- 全部が全部 OOP でなくても良い。(コストやメモリの浪費になってるかも)
そりゃそうだよOOPって「メモリとかCPUとか犠牲にして人様が楽をするため」のものなんですもの。
- すべてのデータをクラスにしようとしないこと。配列も十分便利です。
同上。
尤も「後でデータが追加削除になったとき」の事までをちゃんと視野に入れた上で、なら。
- メソッドを分割しすぎない。(どれを再利用するのかよく考えよう)
まぁ概ねYes。
- メソッドを分割したくなったら後でいくらでもできる。
言い方を変えると「後でいくらでも分割できるようなメソッド/class設計にしやう」。
- もとから用意されてる 関数たち を活用しよう。
えと…時々使い物にならなくて困ってます orz
- 非常に時間のかかる関数 → C言語による拡張モジュール化も検討しよう。
純粋に疑問。現場的にこれをOKにしてくれる現場ってどれくらいあるんでしょ?
おいちゃん的には割と大歓迎なのですがw
ここでちゃんと「ぜんどすたぢお( http://www.zend.co.jp/product/zendstudio.html )」とか推さなきゃw
…って思ったら
本製品は4月24日にて終息いたしました。
え〜。
どうも「ぜんどすたぢお ふぉぉ えっくりっぷす( http://www.zend.co.jp/product/eclipse.html )」が後継らしい。
えくりぷす重いんだよなぁ…
- ループ処理には foreach を使おう。
えと…比較対象はwhile? for? do?
- 複雑なクラスを作ってるなぁと思ったら → Singleton モデルを検討しよう。
なんで「複雑なクラス」がシングルトンに? 思考過程が純粋に不明。
- DB に入れる値なら GET より POST を使おう。(パフォーマンスが上がる)
これも仕組みがよぉわからんなぁ。
- 可能なら正規表現より、ctype_alnum、ctype_alpha、ctype_digit を使おう。
あ久しぶりにしらん関数だった。えと… ext/ctype/ctype.c の中かな? どれどれ…
static PHP_FUNCTION(ctype_alnum)
{
CTYPE(isalnum);
}
で…うわぁCTYPE、マクロだw
んとねぇ156行目あたりから。
なるほどねぇ確かにこれなら早いわっていうか基本C言語のis系使ってるだけぢゃんw
まぁ便利なので記憶しておきませう(っていうかMWのisクラス書き換えようかなぁ…)。
- ファイル指定は basename / file_exists / open_basedir よりフルパス指定が速い。
フルパス指定は却下。
- require_once より require を使おう。(opcode キャッシュがらみの理由で)
onceしないとえらい事になるので却下。
- 一時的なファイルを作るときには tmpfile や tempnam を使おう。
まず「一時ファイルを作らない」設計を考えるのも大切だと思う。ディスク装置って得てして「劇重」だし。
- 外部サービスに XMLHTTP で接続するときにはエラー回避のため Proxy を使おう。
そなの? この辺未検証&未検討〜
- デバッグするときは error_reporting (E_ALL); にしておこう。
まぁ大切。ただ…E_ALLにorしたいbitがあったような気がするんだけど…
- Apache の allowoverride を "none" にしておくとパフォーマンスが向上。
それはApacheのTips。
- 静的なコンテンツには thttpd のような高速なファイルサーバを使おう。
ほほぉ。lighttpdとかってのもあった記憶が。そろそろ「Apache一本槍」も芸がないし。色々チャレンジかなぁ。
- パスなどの設定パラメータは配列に serialize して入れ、キャッシュしておこう。
ん…キャッシュ場所ってどこになるんだべさ?
- アクセスの多いページには PHP の 出力バッファリング を使おう。
これも要注意。
- DB 固有の prepare メソッドではなく PDO::prepare を使おう。
そなの?
- SELECT * (ワイルドカード)を使うのはやめよう。
業務で使ったら「社中引き回しの上おしりペンペン」だと思うのですが?
- PHP より賢い DB ロジック(queries, joins, views, procedures)を活用しよう。
これっていわゆる「SQLに書ける」あれ?
だとすると「DBに負荷をかける事を何よりも忌み嫌う」おいちゃん的にはNGだなぁ。
- SQL の省略表記を活用しよう。
「PHPの最適化」に関係するの?
んむり…うんいくつか得るもの(エルモのってどーゆー変換よ)もあったので。思った以上に面白い考察でした ^^