在PHP中的每次迭代中保留一个计数器变量vs使用count()
在一个无限循环中,我想根据数组中元素的数量进行分解。说:在PHP中的每次迭代中保留一个计数器变量vs使用count(),php,optimization,micro-optimization,Php,Optimization,Micro Optimization,在一个无限循环中,我想根据数组中元素的数量进行分解。说: $myarr = array(); While (True){ //... do something that modifies $myarr ... if (count($myarr) > 100000) { break; } } 问题是,每次我试图以这种方式编写代码时,微型优化的想法都会在我脑海中蔓延(怪我)。我告诉自己:为什么不使用一个变量来跟踪数组中元素的数量呢?像这样: $myarr = array()
$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()在引擎盖下是如何工作的
多谢各位
-Titon如果您正在寻求更快的处理速度,那么第二个代码将执行得更快,因为您没有使用该函数,如果您查找count函数,您可以看到它是从类实现的,我们都知道OOP比过程代码慢。在编写了一点基准脚本之后,我想我已经找到了答案。以下是脚本的代码:
<?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);
}
如我们所见,无论阵列大小如何,单个count()内花费的平均时间大约为0.4微秒
结论:
PHP本身以一种高效的方式跟踪数组中元素的数量(count()的运行时成本为O(1))。不需要使用额外的变量来提高效率
count()对于语法的清晰性和效率来说都是有益的。您应该缓存
count()的结果,这可能不会产生很大的影响,但它仍然是一个简单的优化。调用计数与缓存结果的速度大约慢4倍
代码
你说得对。但我并不担心count()所花费的累积时间是否会因为OOP实现而略微降低代码的速度,而是:在包含数百万个元素的数组上调用count()是明智的吗?count()的“大O性能特征”是什么?OOP比过程代码慢5到10%。每次进入循环时,从变量中进行加减比调用函数快。我认为明智的做法是只使用一次count——在变量初始化时,它会显示元素的数量。“你可以看到它是从类中实现的”?数组不是PHP中的类。这个实现是纯C的。@Dashwuff如果你读过php.net中函数的描述,你会读到下面的“接口只有一个方法,Countable::count(),它返回count()函数的返回值。”所以是的,它是从类实现的。这只在count()时使用
用于作为SPL类实例的对象。数组不是一个对象;这是一种原始类型。
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
$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