在PHP的每次迭代中使用count()保持计数器变量

时间:2012-07-23 07:48:09

标签: php optimization micro-optimization

在无限循环中,我想根据数组中的元素数量进行分解。说:

$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()和array的底层实现。我总是喜欢以更简单的方式编写,如果可以的话,就像第一个代码片段一样。任何人都可以在这个问题上启发我吗?尤其是count()如何在引擎盖下工作?

谢谢。

-Titon

3 个答案:

答案 0 :(得分:1)

写完一个小基准脚本后,我想我找到了答案。这是脚本的代码:

<?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)(内置:2012年6月19日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()在语法清晰度和效率方面都很健康。

答案 1 :(得分: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

答案 2 :(得分:-1)

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