3

これは一種の一般的な質問ですが、それを説明するために具体的な例を使用します。

ドキュメントをロードする関数があります。そのドキュメントが存在しない場合は作成し、存在する場合は JSON 配列に変換します。json_decode()問題があるかどうか、またはファイルが存在しないかどうかにかかわらず、この関数が何らかの配列を返すことを常に望んでいます。現在、私はそのようにやっています...

function load($file) {
    if( ! file_exists($file)) {
        $handle = fopen($file, 'w');
        fclose($handle);
    }

    $raw = file_get_contents($file);
    $contents = json_decode($raw, TRUE);

    return( ! $contents ? array() : $contents);
    //cant use ternary shorthand "?:" in PHP 5.2, otherwise this would be shorter
}

さて、上記のコードには何も問題はありません (少なくとも、問題はないと思いますし、問題なく動作します)。しかし、私はコードを改善し、完全に読みやすく保ちながらコードを凝縮する方法を常に探しています。そして、その return ステートメントは、非効率に見えるので、いつも私を悩ませてきました。それで今日、私は考え始めました、そして何かが私に起こりました。効果のあることをするmysqlチュートリアルを見たのを覚えているconnect() or die();ので、なぜだと思いましたjson_decode() or array();か? これでも機能しますか?だから私は自分の関数を書き直して調べました...

function load($file) {
    if( ! file_exists($file)) {
        $handle = fopen($file, 'w');
        fclose($handle);
    }

    $raw = file_get_contents($file);
    return json_decode($raw, TRUE) or array();
}

そのようで、それは十分に楽しく読むことさえできます。それでは、次の一連の質問に進みます。これは良い習慣ですか?私はそれを理解していますが、他の人はどうですか?それは本当に機能しますか、それともこれはハッピーエンドのバグですか? 調べてみると、私が求めているのは短絡評価と呼ばれるものであり、バグではないことがわかりました。知ってよかったです。私はその新しい用語を使用して検索を絞り込み、さらにいくつかの資料を思いつきました.

ブログエントリー

ウィキペディア

常に MySQL 接続を参照することについて、私が調べている方法でショートサーキットを使用することについて話しているものはほとんどありませんでした。さて、ほとんどの人がこの用語の使用に反対していることは知っていor die()ますが、それはエラーに対処する方法が洗練されていないためです。を使用しようとしていないため、これは私が求めている方法の問題ではありませんor die()。これを使用しない他の理由はありますか?ウィキペディアはそう考えているようですが、C に関してのみです。私は PHP が C で書かれていることを知っているので、それは間違いなく適切な情報です。しかし、この問題は PHP のコンパイルで取り除かれましたか? そうでない場合、それはウィキペディアがそうであるように悪いことですか?

これがウィキペディアのスニペットです。

ウィキペディア- 「短絡は、最新のプロセッサの分岐予測でエラーにつながる可能性があり、パフォーマンスを劇的に低下させる可能性があります (注目すべき例は、レイ トレーシングの軸整列ボックス交差コードを使用した高度に最適化されたレイです) [明確化が必要]。一部のコンパイラはそのようなケースを検出できます。より高速なコードを生成しますが、C 標準に違反する可能性があるため、常に可能であるとは限りません。高度に最適化されたコードは、これを行うために他の方法を使用する必要があります (アセンブリ コードの手動使用など)"

皆さんはどう思いますか?

編集

別のフォーラムを調査したところ、いくつかの良い結果が得られました。一般的なコンセンサスは、この形式の変数割り当ては有効ではあるものの、好まれておらず、現実の世界では悪い形式と見なされることさえあるということです。私は引き続き耳を傾け、何か新しいことがあれば更新します。コービンとマット、特にいくつかのことを片付けてくれたコービンに感謝します。興味のある方は、フォーラムの投稿へのリンクを次に示します

4

3 に答える 3

2

いくつかの異なる質問があるので、それらすべてに対処しようとします。

分岐予測の失敗: C またはアセンブリでコーディングしている場合を除き、これについて心配する必要はありません。PHP では、分岐予測について考えても役に立たないほどハードウェアから離れています。いずれにせよ、これは非常にミクロな最適化であり、特に最初から大規模な文字列解析を行う関数ではそうです。

これを使用しない他の理由はありますか?ウィキペディアはそう考えているようですが、C に関してのみです。私は PHP が C で書かれていることを知っているので、それは間違いなく適切な情報です。

PHP はおそらくそれを別の実行構造に解析します。この関数を何百万回も実行する予定がない限り、またはそれがボトルネックであることがわかっている場合を除き、私はそれについて心配しません。2012 年には、or短絡回路を使用しても 10 億分の 1 秒の差が生じる可能性はほとんどないと思います。

フォーマットに関しては、$a or $bかなり醜いと思います。私の心は、if節で見たのと同じように短絡を理解していません。

if (a() || b())

a() が true と評価されない場合にのみ b() が実行されることは、私の心には完全に明らかです。

でも:

return a() or b();

私には同じ明快さはありません。

これは明らかに単なる意見ですが、どのように書くかについて 2 つの代替案を提示します (私の意見では、どちらのほうが非常に明確です)。

function load($file) {
    if (!file_exists($file)) {
        touch($file);
        return array();
    }

    $raw = file_get_contents($file);

    $contents = json_decode($raw, true);

    if (is_array($contents)) {
        return $contents;
    } else {
        return array();
    }

}

ファイルが実際に作成されるかどうか気にしない場合は、さらに一歩進めることができます。

function load($file) {

    $raw = file_get_contents($file);

    if ($raw !== false) {
        $contents = json_decode($raw, true);
        if ($contents !== null) {
            return $contents;
        }
    }

    return array();

}

これらのコード スニペットは、個人的な好みによるものだと思います。2 番目のスニペットは、おそらく私が使用するものです。クリティカルパスはもう少し明確になる可能性がありますが、わかりやすさを犠牲にすることなく簡潔さを維持しているように感じます.

編集:あなたが関数ごとに1リターンタイプの人なら、次のほうがもう少し好ましいかもしれません:

function load($file) {

    $contents = array();

    $raw = file_get_contents($file);

    if ($raw !== false) {
        $contents = json_decode($raw, true);
        if ($contents === null) {
            $contents = array();
        }
    }

    return $contents;

}
于 2012-05-08T21:52:59.443 に答える
1

コードを可能な限り最小限の行に圧縮することは、常に最良の方法であるとは限りません。通常、コードを圧縮することは非常にクールに見えますが、通常は読みにくいからです。コードと可読性に疑問がある場合は、コードに標準的なコメントを追加して、誰もがコメントだけでコードを理解できるようにすることをお勧めします。

ベストプラクティスに関しては、それは意見の問題であり、それに満足している場合は、それを使用してください。必要に応じて、プロジェクトの後半でいつでもコードを再検討できます

于 2012-05-08T21:53:16.033 に答える
0

1行の変数チェックを行う方法であるため、短絡宣言が好きです。

私が好む:

isset($value) or $value = 0;

それよりも:

if (!isset($value)) {
  $value = 0;
}

しかし、返品に直接使用したことはなく、この投稿を試してみたくなりました.

そして悲しいことに、少なくとも私にとっては、正しく動作しません:

return $data[$key] or $data[1];

配列を期待している間は、すべての場合に値 1 を返します。

以下はスムーズに動作します。

// Make sure $key is valid.
$data[$key] or $key = 1;

return $data[$key];

しかし、$key が $data に存在しない場合でも、PHP がエラーをスローしないことに驚きました。

于 2014-09-04T09:19:40.837 に答える