9

サイズが5MBの配列を持っているので、関数に渡します(参照では渡しません) 。

foo( $arr );

function foo( $arr ) {
    ....
    bar( $arr );
    ....
}

function bar( $arr ) {
    ....
    test( $arr );
    ....
}

function test( $arr ) {
    ....
    test2( $arr );
    ....
}

PHPは、デフォルトで配列値を値(値のコピー)で関数に渡します。

私の質問は、この配列値が100個の関数呼び出しに渡された場合、PHPは100 x 5 MB = 500 MBのメモリを消費しますか?

PHPは、関数呼び出しで(メモリ内で)大きな配列をどのように処理しますか?

4

2 に答える 2

8

テストするコードは次のとおりです。

<?php

    function testnochanges($arr1){
        foreach($arr1 as $val){
            //
        }
        return $arr1;
    }

    function testwithchanges($arr1){
        $arr1[] = 1;
        return $arr1;
    }

    echo "Stage 0: Mem usage is: " . memory_get_usage() . "<br />";

      for ($i = 0; $i < 100000; ++$i) {
        $arr[] = rand();
      }

     echo "Stage 1 (Array Created): Mem usage is: " . memory_get_usage() . "<br />";


     $arrtest1 = testnochanges($arr);
     echo "Stage 2 (Function did NO changes to array): Mem usage is: " . memory_get_usage() . "<br />";

     $arrtest2 = testwithchanges($arr);
     echo "Stage 3 (Function DID changes to array): Mem usage is: " . memory_get_usage() . "<br />";


    ?>

実行後の出力は次のとおりです。

Stage 0: Mem usage is: 330656
Stage 1 (Array Created): Mem usage is: 8855296
Stage 2 (Function did NO changes to array): Mem usage is: 8855352
Stage 3 (Function DID changes to array): Mem usage is: 14179864

ステージ0では、配列が作成される前に、PHPがすでにメモリ内のスペースを使用していることがわかります。最初のアレイ(ステージ1)を作成した後、予想どおりにメモリ使用量に大きな変化が見られます。しかし、関数関数を呼び出してステージ2testnochangesで作成$arrtest1した後、メモリ使用量はそれほど変化していないことがわかります。これは、に変更を加えていないため、同じ配列を指しているためです。しかし、ステージ3では、関数を呼び出し、 PHPに要素を追加して、割り当てられた配列を実行し、メモリのさまざまな部分を使用するようになりました。ここでも、メモリ使用量が大幅に増加しています。$arr$arrtest1$arrtestwithchanges$arrcopy-on-write$arrtest2

乾いた結論:アレイを別のアレイにコピーし、それを変更しない場合、両方のアレイが同じアレイを指しているため、メモリ使用量は同じままです。PHPが実行する配列を変更するcopy-on-writeと、もちろんメモリ使用量が増加します。

読むのが良いこと:ガベージコレクション、パート2に注意してください

于 2012-10-03T06:05:54.397 に答える
2

特定のユースケースがどのように機能するかを実際に知る唯一の方法は、ベンチマークを完了することです(迅速で汚いのは問題ありません)。パフォーマンスに問題がある場合は、SPLを調べることをお勧めします。たとえば、SplFixedArray事前にサイズがわかっていれば、より大きな配列を処理するときにメモリを節約できます。また、新しいバージョンのPHPは、以前のバージョンよりもガベージコレクションをより適切に処理するため、アップグレードも役立つ場合があります。

ベンチマークを実行することにした場合は、これで開始できます(SPLとrawアレイを比較します): https ://github.com/elazar/spl-benchmarks

于 2012-10-03T06:06:00.733 に答える