array_merge foreach
of
In eerste instantie was de foreach loop sneller. Echter, naarmate ik de $foo array ging uitbreiden, werd de array_merge optie sneller!
Iemand hier een verklaring voor?
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
$arrayEen = array(1, 2, 3);
$arrayTwee = array('a', 'b', 'c');
$arrayNieuw = array_merge($arrayEen, $arrayTwee);
print_r($arrayNieuw);
$arrayOmgekeerd = array_merge($arrayTwee, $arrayEen);
print_r($arrayOmgekeerd);
?>
$arrayEen = array(1, 2, 3);
$arrayTwee = array('a', 'b', 'c');
$arrayNieuw = array_merge($arrayEen, $arrayTwee);
print_r($arrayNieuw);
$arrayOmgekeerd = array_merge($arrayTwee, $arrayEen);
print_r($arrayOmgekeerd);
?>
array_merge() voert niet echt een merge uit, maar meer een append. De tweede array wordt gewoon aan de eerste geplakt.
Oké, maar hoe verklaart dat dan waarom in eerste instantie foreach sneller is, maar naarmate de array groter wordt array_merge sneller wordt?
de PHP source code kijken of je iets kan vinden wat dit gedrag verklaard.
Daarvoor zou ik eerst willen weten of dat komt omdat de loop (relatief) trager is geworden of dat de array_merge (relatief) sneller is geworden. Dan kun je eens in En als ik al weet waar ik moet kijken, waar moet ik dan op letten?
Vertel eerst maar eens wat het is. Is foreach trager of array_merge sneller geworden?
Een array met "maar" drie waarden kan anders presteren als dat "zomaar" de drie episoden van de "Lord of the Rings"-trilogie in HD zijn...
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
function test() {
$loops = 500;
$time_1 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 1:
$array_a = array();
$array_b = array(1, 2, 3);
foreach ($array_b as $key => $value) {
$array_a[$key] = $value;
}
}
$time_2 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 2:
$array_a = array();
$array_b = array(1, 2, 3);
array_merge($array_a, $array_b);
}
$time_3 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 3:
$array_a = array();
$array_b = array(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
foreach ($array_b as $key => $value) {
$array_a[$key] = $value;
}
}
$time_4 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 4:
$array_a = array();
$array_b = array(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
array_merge($array_a, $array_b);
}
$time_5 = microtime(true);
echo 'Aantal loops: ' . $loops . '<br>';
echo '<br>';
echo 'OPTIE 1 (foreach): ' . number_format($time_2 - $time_1, 5, ',', '.') . '<br>';
echo 'OPTIE 2 (arrmerg): ' . number_format($time_3 - $time_2, 5, ',', '.') . '<br>';
echo 'OPTIE 3 (foreach): ' . number_format($time_4 - $time_3, 5, ',', '.') . '<br>';
echo 'OPTIE 4 (arrmerg): ' . number_format($time_5 - $time_4, 5, ',', '.') . '<br><br>';
}
test();
test();
test();
?>
function test() {
$loops = 500;
$time_1 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 1:
$array_a = array();
$array_b = array(1, 2, 3);
foreach ($array_b as $key => $value) {
$array_a[$key] = $value;
}
}
$time_2 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 2:
$array_a = array();
$array_b = array(1, 2, 3);
array_merge($array_a, $array_b);
}
$time_3 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 3:
$array_a = array();
$array_b = array(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
foreach ($array_b as $key => $value) {
$array_a[$key] = $value;
}
}
$time_4 = microtime(true);
for ($i = 1; $i <= $loops; $i++) {
// OPTIE 4:
$array_a = array();
$array_b = array(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
array_merge($array_a, $array_b);
}
$time_5 = microtime(true);
echo 'Aantal loops: ' . $loops . '<br>';
echo '<br>';
echo 'OPTIE 1 (foreach): ' . number_format($time_2 - $time_1, 5, ',', '.') . '<br>';
echo 'OPTIE 2 (arrmerg): ' . number_format($time_3 - $time_2, 5, ',', '.') . '<br>';
echo 'OPTIE 3 (foreach): ' . number_format($time_4 - $time_3, 5, ',', '.') . '<br>';
echo 'OPTIE 4 (arrmerg): ' . number_format($time_5 - $time_4, 5, ',', '.') . '<br><br>';
}
test();
test();
test();
?>
En de uitslag:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Aantal loops: 500
OPTIE 1 (foreach): 0,00138
OPTIE 2 (arrmerg): 0,00155
OPTIE 3 (foreach): 0,01514
OPTIE 4 (arrmerg): 0,01105
Aantal loops: 500
OPTIE 1 (foreach): 0,00141
OPTIE 2 (arrmerg): 0,00153
OPTIE 3 (foreach): 0,01504
OPTIE 4 (arrmerg): 0,01106
Aantal loops: 500
OPTIE 1 (foreach): 0,00140
OPTIE 2 (arrmerg): 0,00154
OPTIE 3 (foreach): 0,01505
OPTIE 4 (arrmerg): 0,01099
OPTIE 1 (foreach): 0,00138
OPTIE 2 (arrmerg): 0,00155
OPTIE 3 (foreach): 0,01514
OPTIE 4 (arrmerg): 0,01105
Aantal loops: 500
OPTIE 1 (foreach): 0,00141
OPTIE 2 (arrmerg): 0,00153
OPTIE 3 (foreach): 0,01504
OPTIE 4 (arrmerg): 0,01106
Aantal loops: 500
OPTIE 1 (foreach): 0,00140
OPTIE 2 (arrmerg): 0,00154
OPTIE 3 (foreach): 0,01505
OPTIE 4 (arrmerg): 0,01099
Is het zo duidelijker?
Toevoeging op 25/03/2013 17:37:59:
Je moet array A natuurlijk ook veranderen
Hoe bedoel je?
$array_a = array('a', 'b', 'c');
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Aantal loops: 500
OPTIE 1 (foreach): 0,00153
OPTIE 2 (arrmerg): 0,00236
OPTIE 3 (foreach): 0,01527
OPTIE 4 (arrmerg): 0,01181
Aantal loops: 500
OPTIE 1 (foreach): 0,00150
OPTIE 2 (arrmerg): 0,00236
OPTIE 3 (foreach): 0,01523
OPTIE 4 (arrmerg): 0,01182
Aantal loops: 500
OPTIE 1 (foreach): 0,00153
OPTIE 2 (arrmerg): 0,00237
OPTIE 3 (foreach): 0,01525
OPTIE 4 (arrmerg): 0,01187
OPTIE 1 (foreach): 0,00153
OPTIE 2 (arrmerg): 0,00236
OPTIE 3 (foreach): 0,01527
OPTIE 4 (arrmerg): 0,01181
Aantal loops: 500
OPTIE 1 (foreach): 0,00150
OPTIE 2 (arrmerg): 0,00236
OPTIE 3 (foreach): 0,01523
OPTIE 4 (arrmerg): 0,01182
Aantal loops: 500
OPTIE 1 (foreach): 0,00153
OPTIE 2 (arrmerg): 0,00237
OPTIE 3 (foreach): 0,01525
OPTIE 4 (arrmerg): 0,01187
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
TEST DURATION MEMORY USAGE
------------ ---------- ------------
foreach (0) 0.046953ms 524288
merge (0) 0.057942ms 0
foreach (3) 0.061938ms 262144
merge (3) 0.061938ms 786432
foreach (20) 0.080919ms 524288
merge (20) 0.081918ms 262144
------------ ---------- ------------
foreach (0) 0.046953ms 524288
merge (0) 0.057942ms 0
foreach (3) 0.061938ms 262144
merge (3) 0.061938ms 786432
foreach (20) 0.080919ms 524288
merge (20) 0.081918ms 262144
Elke test is 1000x uitgevoerd. Het getal achter de test naam is het aantal elementen in beide arrays. De foreach test is:
En de merge test is:
Opmerkelijk is dat bij 3 elementen beide manieren hetzelfde werken (de test 3 keer uitgevoerd en 3x hetzelfde getal).
Ook leuk om op te merken is dat wanneer de loop 2 lege arrays krijgt, hij alsnog memory verspilt, de array_merge functie doet dit niet.
Wat ook wel opmerkelijk is dat hij in PHP 5.4.3 CLI mode nooit sneller is dan de foreach.
Quote:
Euh... wat doe je hier nou? Klopt niet helemaal toch? :)
Nee, klopt (ik bedoel, hij klopt niet), typfoutje op het forum.
Gewijzigd op 25/03/2013 20:10:59 door Wouter J
Maar mijn conclusie klopt toch? Bij kleine array foreach sneller, bij grote array array_merge sneller. Hoe kan dat dan?