php foreach, why using pass by reference of a array is fast? -


below test of php foreach loop of big array, thought if $v don't change, real copy not happen because of copy on write, why fast when pass reference?

code 1:

function test1($a){   $c = 0;   foreach($a $v){ if($v=='xxxxx') ++$c; } }  function test2(&$a){   $c = 0;   foreach($a $v){ if($v=='xxxxx') ++$c; } }  $x = array_fill(0, 100000, 'xxxxx');  $begin = microtime(true); test1($x); $end1 = microtime(true); test2($x); $end2 = microtime(true);  echo $end1 - $begin . "\n";   //0.03320002555847 echo $end2 - $end1;           //0.02147388458252 

but time, using pass reference slow.

code 2:

function test1($a){   $cnt = count($a); $c = 0;   for($i=0; $i<$cnt; ++$i)     if($a[$i]=='xxxxx') ++$c; } function test2(&$a){   $cnt = count($a); $c = 0;   for($i=0; $i<$cnt; ++$i)     if($a[$i]=='xxxxx') ++$c; } $x = array_fill(0, 100000, 'xxxxx');  $begin = microtime(true); test1($x); $end1 = microtime(true); test2($x); $end2 = microtime(true);  echo $end1 - $begin . "\n";   //0.024326801300049 echo $end2 - $end1;           //0.037616014480591 

can explain why passing reference fast in code1 slow in code2?

edit: code 2, count($a) makes main difference, time of loop took same.

i thought if $v don't change [foreach($a $v)], real copy not happen because of copy on write, why fast when pass reference?

the impact not on $v on $a, huge array. either pass value or reference function. inside function it's value (test1) or reference (test2).

you have 2 codes (code 1 , code 2).

code 1: using foreach. foreach you've got 2 options: iterate on value or reference (example). when iterate on value, iteration done on copy of value. if iterate on reference, no copy done.

as use reference in test2, it's faster. values not need copied. in test1, pass array value, array gets copied.

code 2: using for. nothing here. in both cases. access variable , read value array. that's pretty same regardless if it's reference or copy (thanks copy on write optimization in php).

you might wonder, why there is difference in code 2. difference not because of for because of count. if pass reference count php internally creates copy of because count needs copy, not reference.

read well: do not use php references johannes schlüter


i've compiled set of tests well. more put code test functions.

  • blank - what's difference in calling function?
  • count - count make difference?
  • for - happens foronly (not count)?
  • foreach - foreach - breaking on first element.

every test in 2 versions, 1 called _copy (passing array copy function) , 1 called _ref (passing array reference).

it's not these micro-benchmarks tell truth, if you're able isolate specific points, can quite educated guess, example not for count had impact:

function blank_copy($a){ } function blank_ref(&$a){ } function foreach_copy($a){     foreach($a $v) break; } function foreach_ref(&$a){     foreach($a $v) break; } function count_copy($a){   $cnt = count($a); } function count_ref(&$a){   $cnt = count($a); } function for_copy($a){     for($i=0;$i<100000;$i++)         $a[$i]; } function for_ref(&$a){     for($i=0;$i<100000;$i++)         $a[$i]; }  $tests = array('blank_copy', 'blank_ref', 'foreach_copy', 'foreach_ref', 'count_copy', 'count_ref', 'for_copy', 'for_ref');   $x = array_fill(0, 100000, 'xxxxx'); $count = count($x); $runs = 10;  ob_start();  for($i=0;$i<10;$i++) {     shuffle($tests);     foreach($tests $test)     {         $begin = microtime(true);         for($r=0;$r<$runs;$r++)             $test($x);         $end = microtime(true);         $result = $end - $begin;         printf("* %'.-16s: %f\n", $test, $result);     } }  $buffer = explode("\n", ob_get_clean()); sort($buffer); echo implode("\n", $buffer); 

output:

* blank_copy......: 0.000011 * blank_copy......: 0.000011 * blank_copy......: 0.000012 * blank_copy......: 0.000012 * blank_copy......: 0.000012 * blank_copy......: 0.000015 * blank_copy......: 0.000015 * blank_copy......: 0.000015 * blank_copy......: 0.000015 * blank_copy......: 0.000020 * blank_ref.......: 0.000012 * blank_ref.......: 0.000012 * blank_ref.......: 0.000014 * blank_ref.......: 0.000014 * blank_ref.......: 0.000014 * blank_ref.......: 0.000014 * blank_ref.......: 0.000015 * blank_ref.......: 0.000015 * blank_ref.......: 0.000015 * blank_ref.......: 0.000015 * count_copy......: 0.000020 * count_copy......: 0.000022 * count_copy......: 0.000022 * count_copy......: 0.000023 * count_copy......: 0.000024 * count_copy......: 0.000025 * count_copy......: 0.000025 * count_copy......: 0.000025 * count_copy......: 0.000026 * count_copy......: 0.000031 * count_ref.......: 0.113634 * count_ref.......: 0.114165 * count_ref.......: 0.114390 * count_ref.......: 0.114878 * count_ref.......: 0.114923 * count_ref.......: 0.115106 * count_ref.......: 0.116698 * count_ref.......: 0.118077 * count_ref.......: 0.118197 * count_ref.......: 0.123201 * for_copy........: 0.190837 * for_copy........: 0.191883 * for_copy........: 0.193080 * for_copy........: 0.194947 * for_copy........: 0.195045 * for_copy........: 0.195944 * for_copy........: 0.198314 * for_copy........: 0.198878 * for_copy........: 0.200016 * for_copy........: 0.227953 * for_ref.........: 0.191918 * for_ref.........: 0.194227 * for_ref.........: 0.195952 * for_ref.........: 0.196045 * for_ref.........: 0.197392 * for_ref.........: 0.197730 * for_ref.........: 0.201936 * for_ref.........: 0.207102 * for_ref.........: 0.208017 * for_ref.........: 0.217156 * foreach_copy....: 0.111968 * foreach_copy....: 0.113224 * foreach_copy....: 0.113574 * foreach_copy....: 0.113575 * foreach_copy....: 0.113879 * foreach_copy....: 0.113959 * foreach_copy....: 0.114194 * foreach_copy....: 0.114450 * foreach_copy....: 0.114610 * foreach_copy....: 0.118020 * foreach_ref.....: 0.000015 * foreach_ref.....: 0.000016 * foreach_ref.....: 0.000016 * foreach_ref.....: 0.000016 * foreach_ref.....: 0.000018 * foreach_ref.....: 0.000019 * foreach_ref.....: 0.000019 * foreach_ref.....: 0.000019 * foreach_ref.....: 0.000019 * foreach_ref.....: 0.000020 

Comments

Popular posts from this blog

objective c - Change font of selected text in UITextView -

php - Accessing POST data in Facebook cavas app -

c# - Getting control value when switching a view as part of a multiview -