我无法按照konforces答案下方评论中给出的测量结果进行跟踪,但是这种方法比使用refs的foreach略微更快:
$c=count($array);
for(
$i=0;
$i<$c
;
$array[$i]=$array[$i]['bleh'],
$i++
);
不会说实际测量起来很琐碎,但时间会根据先后顺序有所变化,这是针对包含一千万个成员的数组进行的测试,如问题所述:
foreach ref: 4.192161
foreach key: 4.383342
foreach copy: 4.222771
array_map lambda: 12.240275
array_map reset: 16.401093
for key: 3.459406
for copy: 4.690722
脚本:
ini_set('memory_limit', -1);
$arrayCount = 10000000;
$test = 'just run';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$array = end($array);
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$array = array_map(function(){}, $array);
$test = 'foreach ref';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
foreach($array as &$v) $v = $v['bleh'];
unset($v);
$diff = microtime(1)-$start;
$tests[$test] = $diff;
printf("%s: %f\n", $test, $diff);
$test = 'foreach key';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
foreach($array as $k => $v) $array[$k] = $v['bleh'];
$diff = microtime(1)-$start;
$tests[$test] = $diff;
printf("%s: %f\n", $test, $diff);
$test = 'foreach copy';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
foreach($array as $k => $v) $arrayb[] = $v['bleh'];
$diff = microtime(1)-$start;
$tests[$test] = $diff;
unset($arrayb);
printf("%s: %f\n", $test, $diff);
$test = 'array_map lambda';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
$array = array_map(function($e) { return $e['bleh']; }, $array);
$diff = microtime(1)-$start;
$tests[$test] = $diff;
printf("%s: %f\n", $test, $diff);
$test = 'array_map reset';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
$array = array_map('reset', $array);
foreach($array as $k => $v) $arrayb[] = $v['bleh'];
$diff = microtime(1)-$start;
$tests[$test] = $diff;
printf("%s: %f\n", $test, $diff);
$test = 'for key';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
for($i=0,$c=count($array);$i<$c;$array[$i]=$array[$i]['bleh'],++$i);
$diff = microtime(1)-$start;
$tests[$test] = $diff;
printf("%s: %f\n", $test, $diff);
$test = 'for copy';
$array = array_fill(0, $arrayCount, array("bleh" => 109720,));
$start = microtime(1);
for($i=0,$c=count($array);$i<$c;$arrayb[]=$array[$i]['bleh'],++$i);
$diff = microtime(1)-$start;
$tests[$test] = $diff;
unset($arrayb);
printf("%s: %f\n", $test, $diff);
$l = count($a); for ($i=0; $i<$l; ++$i) $a[$i] = $a[$i]['bleh'];
这样的代码更快且占用更少的内存,但是这种差异真的有意义吗?通常应该专注于选择适当的算法(每个答案本质上都是相同的),编写易于理解的代码,而不要过分担心微小的优化。 - Matthewforeach
示例最易读,因为你一看就能理解它,不需要文档)。但就执行速度而言,这个示例比foreach
示例慢两倍,而reset
示例比这个还要慢两倍。如果你有很多值,你会看到差异的。 - ridfor
的例子只比foreach
略慢一点(无关紧要的慢)。我进行了基准测试,我的评论不仅仅基于个人经验。我也不主张过早优化,也不是仅仅因为我说它不好就说“不要这样做”,我只是提出了一个论点。我以艰苦的方式发现选择快速且易于阅读的解决方案有多么重要。如果你经常使用良好的实践方法,那么从长远来看你将会少受折磨。 - rid