一回も披露したことのない豆知識

プログラムをはじめたばかりの初心者なので見当違いな事を質問していたらすみません。


他人のコードを見ていた時に以下のようなコードがありました。

if( pathinfo($file,PATHINFO_EXTENSION)=="txt" ||
pathinfo($file,PATHINFO_EXTENSION)=="php" ||
pathinfo($file,PATHINFO_EXTENSION)=="csv"){

処理.....
}
※実際は条件でのpathinfo部分がもっと長いです。

で、気になったのがこれだと条件チェックする際に毎回pathinfoが呼ばれるのでは?
というところです。

条件前に
$hoge = pathinfo($file);
としておき
if($hoge['extension'] == 'txt' || $hoge['extension'] == 'php')

などと記述した方が、pathinfoの呼び出しは一回のため速度的にも見た目的にも
いいのではないでしょうか?

気になったので
echo で pathinfo($file,PATHINFO_EXTENSION)を連続で出力するメソッドと
配列に格納した上で $hoge['extension']を連続出力するメソッドのtimeを測定してみたところ
メッソド呼び出しを毎回行う方が高速になりました。
(高速といってもたいしたことありませんが)


個人的には配列に入れた方が早い気がしていたのですが
この考え自体が間違った考えなのでしょう?
基本を知らないので検討違いな事言っていたらご指摘いただければ幸いです。

現在プログラムを勉強中なのですが、こんな事どーでもいいのかもしれませんが
なんとなく気になったので質問させて頂いた次第です。

A 回答 (3件)

> メソッド呼び出しを毎回行う方が高速になりました。



phpに限らず、あらゆる言語処理系は、ソースコードを逐一解釈するわけでなく、ラインタイムライブラリへで動作させる内部コードへのの変換において、「ロジックの先読み」などの最適化処理を行います。
また実行時も、プロセスキャッシュのような機能を使い、高速化を意識しています。
そのため、配列などへのインラインアクセスより、組込オブジェクトによるアクセスのほうが高速であるのは、javaやC#のようなコンパイラ処理系ではよくある話です。

phpのようなインタプリタ処理系では、このあたりの能力がかなり落ちるのですが、そのベンチマークが正しいとすると、zendの実行エンジンも結構頑張っていると言えるのでは。
    • good
    • 0

> などと記述した方が、pathinfoの呼び出しは一回のため速度的にも


> 見た目的にもいいのではないでしょうか?

おおむねそうだと思います。確かにあなたのようにpathinfoを一度だけ呼びその結果を変数に格納したものを使いまわす方がよりよい書き方だとは思います。ただ処理速度に困っていて極限まで速くする必要があるという場合でもない限りはそれほどこだわる必要はないかもしれません。


よりよい書き方にこだわるのなら…、pathinfoの呼び出しを1回にしても拡張子の判定で結局何度も比較を行うのではそこも冗長だと思います。さらに、比較する拡張子が2つだったり3つになったりもっと増えたりと増減する場合や、小文字だけしか許さないようになっているが大文字でも動くようにする場合などを考慮すると、以下のようにした方がスマートだと思います。

if (preg_match('/^(txt|php|csv)$/i', $hoge['extension'])) {
    • good
    • 0

>> pathinfoの呼び出しは一回のため速度的にも見た目的にもいいのではないでしょうか?



その通りです。

>> メッソド呼び出しを毎回行う方が高速になりました。

測定ミスな気が…


まずこれならば「==」ではなく「===」を用いたほうがごく僅かですが速くなります。速さ云々じゃなくて「==」「!=」は曖昧さが嫌いなので私は「===」「!==」を使って書くように一貫していますね。

if (pathinfo($file,PATHINFO_EXTENSION)==="txt" ||
pathinfo($file,PATHINFO_EXTENSION)==="php" ||
pathinfo($file,PATHINFO_EXTENSION)==="csv") { ... }

これでもかなり冗長なので私なら間違いなく以下のように書くと思います。第3引数のTrue指定は「==」ではなく「===」を比較に使用するという意味です。

$ext = pathinfo($file, PATHINFO_EXTENSION);
$list = array("txt", "php", "csv");
if (in_array($ext, $list, true)) { ... }

更に極限まで高速化するならば、in_arrayではなくissetを使えるように書くといいでしょう。前者の速度は O(n) ですが、後者の速度は O(1) です。実質的にはほとんど差が無い上にコード自体は書きにくくなるので先ほどのin_arrayの例で十分だと思いますが…(笑

$ext = pathinfo($file, PATHINFO_EXTENSION);
$hash = array("txt" => "", "php" => "", "csv" => "");
if (isset($hash[$ext])) { ... }

あ、複数ファイルに対してこれを行う場合は $list とか $hash の生成を1回だけにしておくのは当然の配慮ですね。ループの外側に持ってくるだけでもいいし、場合によってはstatic変数として宣言するのもありだと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!