Ich dachte, wenn die $v
ändern Sie nicht [ foreach($a as $v)
], wird die echte Kopie nicht stattfinden, weil Kopie auf Schreiben aber warum ist es so schnell, wenn es durch eine Referenz übergeben wird?
Die Auswirkungen sind nicht auf $v
sondern auf $a
, das riesige Feld. Sie übergeben es entweder als Wert oder als Referenz an die Funktion. Innerhalb der Funktion ist es dann ein Wert (test1) oder ein Verweis (test2).
Sie haben zwei Codes (Code 1 und Code 2).
Code 1: Wird mit foreach
. Mit foreach
haben Sie zwei Möglichkeiten: Iterieren Sie über einen Wert oder eine Referenz ( Beispiel ). Wenn Sie über einen Wert iterieren, wird die Iteration auf einer kopieren. des Wertes. Wenn Sie über eine Referenz iterieren, wird keine Kopie erstellt.
Da Sie die Referenz in test2 verwenden, ist es schneller. Die Werte müssen nicht kopiert werden. Aber in test1, übergeben Sie das Array als Wert, wird das Array kopiert.
Code 2: Wird mit for
. Denn eigentlich tut sich hier nichts. In beiden Fällen. Sie greifen auf die Variable zu und lesen den Wert aus dem Array. Das ist so ziemlich dasselbe, egal ob es sich um eine Referenz oder eine Kopie handelt (dank der Kopie auf Schreiben Optimierung in PHP).
Sie fragen sich jetzt vielleicht, warum es ist ein Unterschied im Code 2. Der Unterschied ist nicht auf die for
sondern wegen der count
. Wenn Sie einen Verweis auf count
PHP erstellt intern eine Kopie davon, weil es count
braucht eine Kopie, keine Referenz.
Lesen Sie auch: Verwenden Sie keine PHP-Referenzen von Johannes Schlüter
Ich habe auch eine Reihe von Tests zusammengestellt. Aber ich habe den Code in die Testfunktionen eingefügt.
- Blank - Worin besteht der Unterschied beim Aufruf der Funktion?
- Zählen - Hat
count
einen Unterschied machen?
- Für - Was passiert mit
for
nur (nicht count
)?
- Foreach - Einfach
foreach
- sogar beim ersten Element brechen.
Jeder Test liegt in zwei Versionen vor, die eine heißt _copy
(Übergabe des Arrays als Kopie an die Funktion) und eine mit dem Namen _ref
(Übergabe des Arrays als Referenz).
Nicht immer sagen diese Mikro-Benchmarks die Wahrheit, aber wenn man in der Lage ist, bestimmte Punkte zu isolieren, kann man sehr wohl eine fundierte Vermutung anstellen, zum Beispiel, dass nicht for
pero count
hatte die Auswirkungen:
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, 100000, '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: %f\n", $test, $result);
}
}
$buffer = explode("\n", ob_get_clean());
sort($buffer);
echo implode("\n", $buffer);
Ausgabe:
* 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