0

無限ループで、配列の要素数に基づいて抜け出したい。言う:

$myarr = array();

While (True){
    //... do something that modifies $myarr ...
    if (count($myarr) > 100000) { break; }
}

問題は、この方法でコーディングしようとするたびに、マイクロ最適化の考えが私の頭に忍び寄ることです (私のせいです)。配列内の要素数を追跡するために変数を使用しないのはなぜですか? このような:

$myarr = array();
$n_myarr = 0;

while (True){
    // ... do something that modifies $myarr
    if ( ... elements added ... )
        { $n_myarr += $n_elements_added; }

    else if ( ... elements removed ... )
        { $n_myarr -= $n_elements_removed; }

    if ($n_myarr > 1000000) { break; }
}

私が理解している限り、count() がどのように実行されるかは、count() と配列の基になる実装に完全に依存しています。できれば、最初のコード スニペットのように、できるだけ簡単な方法で書くことを常に好みます。誰かがこの主題について私を啓発できますか? 特に、内部では count() はどのように機能するのでしょうか?

ありがとうございました。

-ティトン

4

3 に答える 3

2

ちょっとしたベンチマーク スクリプトを書いた後、私は自分の答えを見つけたと思います。スクリプトのコードは次のとおりです。

<?php

$n_iteration = 1e7;

$test_sizes = array(
    1e2, 1e3, 1e4, 1e5, 1e6, 2e6, 3e6, 4e6, 5e6
);

foreach ($test_sizes as $test_size){
    $test_array = range(1, $test_size);

    $start_time = microtime(true);

    for ($i = 0; $i < $n_iteration; $i++)
        { $x = count($test_array); }

    $end_time = microtime(true);
    $interval = $end_time - $start_time;
    printf(
        "Iterations: %d, Size: %8.d,"
        ." Total time: %6.3f sec, Avg. time: %1.3e sec\n",
        $n_iteration, $test_size, $interval, $interval/$n_iteration);

}

「PHP 5.4.4-2 (cli) (built: Jun 19 2012 07:38:55)」を使用してマシンでスクリプトを実行すると、次の出力が生成されます。

Iterations: 10000000, Size:      100, Total time:  3.548 sec, Avg. time: 3.548e-7 sec
Iterations: 10000000, Size:     1000, Total time:  3.368 sec, Avg. time: 3.368e-7 sec
Iterations: 10000000, Size:    10000, Total time:  3.549 sec, Avg. time: 3.549e-7 sec
Iterations: 10000000, Size:   100000, Total time:  3.407 sec, Avg. time: 3.407e-7 sec
Iterations: 10000000, Size:  1000000, Total time:  4.557 sec, Avg. time: 4.557e-7 sec
Iterations: 10000000, Size:  2000000, Total time:  3.263 sec, Avg. time: 3.263e-7 sec
Iterations: 10000000, Size:  3000000, Total time:  3.574 sec, Avg. time: 3.574e-7 sec
Iterations: 10000000, Size:  4000000, Total time:  4.047 sec, Avg. time: 4.047e-7 sec
Iterations: 10000000, Size:  5000000, Total time:  3.628 sec, Avg. time: 3.628e-7 sec

ご覧のとおり、平均。単一の count() 内で費やされる時間は、配列のサイズに関係なく、約 0.4 マイクロ秒でほぼ一定です。

結論:

PHP 自体は、効率的な方法で配列内の要素の数を追跡します (count() は O(1) のランタイム コストを持ちます)。効率化のために追加の変数を使用する必要はありません。

count() は、構文の明確さと効率の両方において健全です。

于 2012-07-23T19:59:44.050 に答える
0

関数を使用していないため、より高速な処理を求めている場合は、2 番目のコードの方が高速に実行されます。クラスから実装されていることを確認してください。OOP は手続き型コードよりも遅いことがわかっています。

于 2012-07-23T07:54:43.353 に答える