php foreach,为什么使用数组引用传递速度快?
下面是对一个大数组的php foreach循环的测试,我认为如果$v不改变,真正的副本不会因为写入时的副本而发生,但为什么它通过引用传递时速度快?
代码1: function test1($a){ $c = 0; foreach($a as $v){ if($v=='xxxxx') ++$c; } } function test2(&$a){ $c = 0; foreach($a as $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 但这一次,使用pass by reference很慢. 代码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,'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 有人可以解释为什么通过引用传递在code1中速度快但在code2中速度慢吗? 编辑:
影响不在$v上,而在$a,庞大的阵列上.您可以将其作为值传递或作为函数的引用传递.在函数内部,然后是值(test1)或引用(test2). 你有两个代码(代码1和代码2). 代码1:正在使用foreach.使用foreach,您有两个选择:迭代值或引用(Example).迭代值时,迭代将在值的副本上完成.如果迭代引用,则不会执行任何复制. 当您在test2中使用引用时,它会更快.不需要复制值.但是在test1中,您将数组作为值传递,数组将被复制. 代码2:正在使用.因为这里什么也没做.在这两种情况下.您可以从数组中访问变量和读取值.无论是引用还是副本(这要归功于PHP中的写入优化副本),这几乎是一样的. 您现在可能想知道,为什么代码2存在差异.差异不是因为for而是因为计数.如果你传递一个引用计数PHP内部创建它的副本,因为它计数需要一个副本,而不是一个引用. 阅读:Do not use PHP references by Johannes Schlüter 我也编译了一组测试.但我更具体地将代码放入测试函数中. >空白 – 调用函数有什么区别? 每个测试都有两个版本,一个名为_copy(将数组作为副本传递给函数),另一个名为_ref(将数组作为参考传递). 并不总是这些微基准测试告诉你真相,但如果你能够隔离特定点,你可以很好地做出有根据的猜测,例如,不是因为计数产生了影响: function blank_copy($a){ } function blank_ref(&$a){ } function foreach_copy($a){ foreach($a as $v) break; } function foreach_ref(&$a){ foreach($a as $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,'xxxxx'); $count = count($x); $runs = 10; ob_start(); for($i=0;$i<10;$i++) { shuffle($tests); foreach($tests as $test) { $begin = microtime(true); for($r=0;$r<$runs;$r++) $test($x); $end = microtime(true); $result = $end - $begin; printf("* %'.-16s: %fn",$test,$result); } } $buffer = explode("n",ob_get_clean()); sort($buffer); echo implode("n",$buffer); 输出: * 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |