1

コピーオンライトは基本的にパフォーマンスを同等にするため、PHPで参照を渡すのは、技術的な理由がある場合にのみ行うことを十分に説明しています。私が理解していることから、それが変更されない場合、オブジェクトをコピーすることはありません。

しかし、関数が変数を変更しても、コードがそれを二度と使用しない/変更された部分を使用しない場合はどうなりますか?オリジナルが変更されているかどうかはコードに関係ありません。はい、PHPオプティマイザーがこの状況を考慮に入れている可能性はありますが、私はそれを信じる理由はありません。

また、単一の参照を渡すことは、巨大な配列やオブジェクトをコピーするよりもはるかに高速になるはずです。

それで、これは参照で渡すのに良い状況ですか?

たとえば、DomCrawlerを渡すとします(この特定の場合に暗黙的に参照によって渡されることを除いて、大きな[html形式の]文字列を超えない)。少しクロールして、いくつかの情報を抽出します。多くの場合、クローラーを再び使用しないため、クローラーを元の位置にリセットする必要はありません。また、後者でDOMCrawlerを使用していると想像してください。そこから、URIを読み取ります。関数はこれを変更しなかったので、参照または値による受け渡しは依然として同等ですが、参照による受け渡しは大幅に最適ではありませんか?この状況は、オプティマイザーが見つけるのは非常に難しいと思います。

4

3 に答える 3

3

それで、これは参照で渡すのに良い状況ですか?

いいえ。

わかった。$ bigStringがあり、それを関数に渡すと、関数はそれを変更して何かを実行し、呼び出し元はそれを二度と必要としないと想像してください。参照による受け渡しは、コピーを回避するため、最初は高速です。しかし、それはまだ悪い考えです。

(1)別の呼び出し元が、その変数の使用を継続たい関数を呼び出すと、問題が発生します。基本的に、参照はカプセル化に違反します。

(2)その値を参照する関数の外部に複数の非参照変数があるとすぐに、参照を作成するだけで再度コピーが必要になります。(変数値は、非参照(copy-on-modify)または参照(modifyで特別なことは何もしない)のいずれかであるコンテナーに保持されるため、参照変数および非参照変数は、同時に、複製する必要があります。)

(3)上記の理由により、関数内でstrlenを呼び出すのと同じくらい無害なものは、値を複製する必要があります。これは、strlenのパラメーターが標準である値によって渡されるためです。ここで、substrなどのいくつかの関数を呼び出し、ループでstrlenを実行し、毎回データの新しいコピーを作成していると想像してください。

(4)DDR3RAMは1秒あたり約10GBを超える可能性があり、CPUキャッシュRAMはどれだけ速いかを知っています。PHPのパフォーマンスについては、文字列または配列のコピーにかかる時間よりも大きな問題があると思います。

迷信的なパフォーマンスの向上のために参照を使用しないでください。それは決して機能しません。

本当にコピーを避けたい場合、これを行う正しい方法は、おそらく変数を処理するオブジェクトのメソッドとして関数を配置することです。

class Thing {
    private $bigString;

    public function foo() {
        $this->bigString[0] = 'x';
    }
}

次に、コピーを回避し、カプセル化のメリットを享受し、参照の微妙な点を排除します。

PS:DomCrawlerはオブジェクトであるため、良い例ではありません。PHPオブジェクトはとにかくコピーオンライトになることはありません(そうだと思いますが、間接参照のレベルが追加されているため、コピーオンライトであるのは小さなポインターコンテナーなどだけです)。

于 2013-03-11T17:56:32.693 に答える
1

gotoを避けるのと同じ理由で、私は常に参照による受け渡しを避けてきました。

$a = myFunction($a);

読みやすく、再利用しやすいmyFunction(&$a);

于 2013-08-27T12:54:03.053 に答える
0

PHPシステムの私の理解から、すべてが「参照」によって渡されます。したがって、巨大な配列やオブジェクトを渡す場合、それらは常に「参照」によって渡されます。

ここに2つの異なるタイプがあるため、「参照」を引用符で囲みます。

  • 明示的な参照は、参照として追跡することをphpに指定する場所です
  • 暗黙の参照は、値として追跡する場所です。

PHPのデフォルトは暗黙の参照です。

したがって、暗黙的な参照を変更するまで、パフォーマンスへの影響はありません。この場合、PHPは値を個別のメモリアドレスにコピーして割り当て、参照を更新します。

コンパイラが変数が使用されなくなったか、スコープ内にないことを検出すると、GCはそれをすくい上げます。

于 2013-03-11T06:42:57.187 に答える