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

如果您正在寻求更快的处理速度,第二个代码将执行得更快,因为您没有使用该功能,如果您寻找计数功能http://bg2.php.net/manual/en/function.count.php您可以看到它是从一个类中实现的,而且我们都知道 OOP 比过程代码慢。

于 2012-07-23T07:54:43.353 回答
0

你应该缓存 的结果count(),它可能不会有太大的不同,但它仍然是一个简单的优化。调用计数与缓存结果大约慢 4 倍。

代码

$array = range(0,100000);

for($x = 100; $x <= 1000000; $x += 100) {

    $countResults = [];
    $staticResults = [];

    for($i = 0; $i < $x; $i++) {

        $start = microtime(true);
        for($j = 0; $j < count($array); $j++) {}
        $end = microtime(true);

        $countResults[] = $end-$start;

        $start = microtime(true);
        $size = count($array);
        for($j = 0; $j < $size; $j++) {}
        $end = microtime(true);

        $staticResults[] = $end-$start;

    }

    $countSum = array_sum($countResults);

    echo sprintf(
         "Count  - Iterations: %d; Total Time: %05.6f; Avg time: %05.6f\n",
         $x,
         $countSum,
         $countSum/$x
     );

    $staticSum = array_sum($staticResults);

    echo sprintf(
         "Static - Iterations: %d; Total Time: %05.6f; Avg time: %05.6f\n",
         $x,
         $staticSum,
         $staticSum/$x
     );

}

结果:

Count  - Iterations: 100; Total Time: 0.962752; Avg time: 0.009628
Static - Iterations: 100; Total Time: 0.253768; Avg time: 0.002538
Count  - Iterations: 200; Total Time: 2.258045; Avg time: 0.011290
Static - Iterations: 200; Total Time: 0.579273; Avg time: 0.002896
Count  - Iterations: 300; Total Time: 2.907984; Avg time: 0.009693
Static - Iterations: 300; Total Time: 0.786796; Avg time: 0.002623
Count  - Iterations: 400; Total Time: 3.756074; Avg time: 0.009390
Static - Iterations: 400; Total Time: 1.004253; Avg time: 0.002511
Count  - Iterations: 500; Total Time: 5.086776; Avg time: 0.010174
Static - Iterations: 500; Total Time: 1.363288; Avg time: 0.002727
Count  - Iterations: 600; Total Time: 6.626471; Avg time: 0.011044
Static - Iterations: 600; Total Time: 1.793517; Avg time: 0.002989
Count  - Iterations: 700; Total Time: 6.780818; Avg time: 0.009687
Static - Iterations: 700; Total Time: 1.816578; Avg time: 0.002595
Count  - Iterations: 800; Total Time: 7.640220; Avg time: 0.009550
Static - Iterations: 800; Total Time: 2.026010; Avg time: 0.002533
Count  - Iterations: 900; Total Time: 8.436923; Avg time: 0.009374
Static - Iterations: 900; Total Time: 2.237418; Avg time: 0.002486
Count  - Iterations: 1000; Total Time: 9.483782; Avg time: 0.009484
Static - Iterations: 1000; Total Time: 2.520293; Avg time: 0.002520
Count  - Iterations: 1100; Total Time: 10.492371; Avg time: 0.009539
Static - Iterations: 1100; Total Time: 2.803949; Avg time: 0.002549
Count  - Iterations: 1200; Total Time: 11.305185; Avg time: 0.009421
Static - Iterations: 1200; Total Time: 3.027705; Avg time: 0.002523
Count  - Iterations: 1300; Total Time: 12.249071; Avg time: 0.009422
Static - Iterations: 1300; Total Time: 3.265644; Avg time: 0.002512
Count  - Iterations: 1400; Total Time: 13.166538; Avg time: 0.009405
Static - Iterations: 1400; Total Time: 3.499845; Avg time: 0.002500
Count  - Iterations: 1500; Total Time: 14.204276; Avg time: 0.009470
Static - Iterations: 1500; Total Time: 3.776997; Avg time: 0.002518
Count  - Iterations: 1600; Total Time: 15.280157; Avg time: 0.009550
Static - Iterations: 1600; Total Time: 4.076611; Avg time: 0.002548
Count  - Iterations: 1700; Total Time: 15.938380; Avg time: 0.009376
Static - Iterations: 1700; Total Time: 4.246082; Avg time: 0.002498
Count  - Iterations: 1800; Total Time: 16.967943; Avg time: 0.009427
Static - Iterations: 1800; Total Time: 4.493304; Avg time: 0.002496
Count  - Iterations: 1900; Total Time: 17.870854; Avg time: 0.009406
Static - Iterations: 1900; Total Time: 4.749316; Avg time: 0.002500
Count  - Iterations: 2000; Total Time: 18.900052; Avg time: 0.009450
Static - Iterations: 2000; Total Time: 5.038069; Avg time: 0.002519
Count  - Iterations: 2100; Total Time: 20.487390; Avg time: 0.009756
Static - Iterations: 2100; Total Time: 5.480530; Avg time: 0.002610
Count  - Iterations: 2200; Total Time: 21.328690; Avg time: 0.009695
Static - Iterations: 2200; Total Time: 5.671044; Avg time: 0.002578
Count  - Iterations: 2300; Total Time: 22.270163; Avg time: 0.009683
Static - Iterations: 2300; Total Time: 5.906530; Avg time: 0.002568
Count  - Iterations: 2400; Total Time: 23.392992; Avg time: 0.009747
Static - Iterations: 2400; Total Time: 6.225149; Avg time: 0.002594
Count  - Iterations: 2500; Total Time: 24.346405; Avg time: 0.009739
Static - Iterations: 2500; Total Time: 6.494287; Avg time: 0.002598
于 2017-08-23T15:21:24.850 回答