In een PHP-project waar ik mee bezig ben constateerde ik absurd geheugen gebruik. Dat nodigde uit tot experimenteren.
Daarbij liep ik tegen een absurd geheugengebruik van arrays aan.
Ik heb het volgende experimentele script gemaakt:
Daaruit blijkt op mijn PC het volgende:
De vraag. Is dit normaal?
Een array met 30.000 keer de string 'Hoi' blijkt meer dan 7 MB geheugen te nemen.
Er vanuit gaande dat de string 4 bytes groot is incl. zero aan het eind, en de key een integer is van 4 bytes, zou deze string naar verwachting 4 x 30.000 = 120.000 bytes geheugen nemen. Uiteraard is er overhead aangezien PHP realtime interpreteert. Echter meer dan het 50-voudige vind ik wel heel extreem.
Het blijkt echt door de array te komen want vrijgeven dmv. unset levert weer het geheugen gebruik bij aanvang op. Ook de string vervangen door een numerieke waarde geeft hetzelfde verschijnsel.
Verder experimenteren. Array weer maken, serializen en originele array weggooien. Dezelfde data neemt nu stukken minder. Niet praktisch om mee te werken natuurlijk, maar het toont wel iets aan.
Vervolgens een string maken. Deze heb ik zelfs 10 keer zo groot gemaakt, want een array bevat meer data dan alleen de waardes, namelijk de keys, en een string is veel simpeler. Maar zelfs dan is het geheugengebruik van de string vele malen kleiner.
Dit experiment laat nog iets zien: Hoe efficient de string in het geheugen wordt opgeslagen. De toename van het geheugengebruik na het maken van de lange string is amper groter dan de werkelijke lengte van de string.
Is het normaal dat PHP zo inefficient met arrays om gaat? Want als dat zo is, dan moet je vooral grote arrays gaan mijden.
Daarbij liep ik tegen een absurd geheugengebruik van arrays aan.
Ik heb het volgende experimentele script gemaakt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <?php echo 'Memory [begin]: '.intval(memory_get_usage()/1024) . ' KB<br>'; $t=array(); for ($i=0; $i<30000; $i++) $t[]='Hoi'; echo 'Memory [na maken array]: '.intval(memory_get_usage()/1024) . ' KB<br>'; unset($t); echo 'Memory [na unset array]: '.intval(memory_get_usage()/1024) . ' KB<br>'; $t=array(); for ($i=0; $i<30000; $i++) $t[]='Hoi'; $t=serialize($t); echo 'Memory [memory na serialize array]: '.intval(memory_get_usage()/1024) . ' KB<br>'; $t=''; for ($i=0; $i<300000; $i++) $t.='Hoi'; echo 'Memory [na maken string]: '.intval(memory_get_usage()/1024) . ' KB<br>'; echo 'Hoeveelheid bytes in string (uitgedrukt in KB) ' . intval(strlen($t)/1024) . '<br>'; unset($t); echo 'Memory [na unset string]: '.intval(memory_get_usage()/1024) . ' KB<br>'; |
Daaruit blijkt op mijn PC het volgende:
code:
1
2
3
4
5
6
7
8
| Memory [begin]: 106 KB Memory [na maken array]: 7629 KB Memory [na unset array]: 106 KB Memory [memory na serialize array]: 623 KB Memory [na maken string]: 985 KB Hoeveelheid bytes in string (uitgedrukt in KB) 878 Memory [na unset string]: 106 KB ?> |
De vraag. Is dit normaal?
Een array met 30.000 keer de string 'Hoi' blijkt meer dan 7 MB geheugen te nemen.
Er vanuit gaande dat de string 4 bytes groot is incl. zero aan het eind, en de key een integer is van 4 bytes, zou deze string naar verwachting 4 x 30.000 = 120.000 bytes geheugen nemen. Uiteraard is er overhead aangezien PHP realtime interpreteert. Echter meer dan het 50-voudige vind ik wel heel extreem.
Het blijkt echt door de array te komen want vrijgeven dmv. unset levert weer het geheugen gebruik bij aanvang op. Ook de string vervangen door een numerieke waarde geeft hetzelfde verschijnsel.
Verder experimenteren. Array weer maken, serializen en originele array weggooien. Dezelfde data neemt nu stukken minder. Niet praktisch om mee te werken natuurlijk, maar het toont wel iets aan.
Vervolgens een string maken. Deze heb ik zelfs 10 keer zo groot gemaakt, want een array bevat meer data dan alleen de waardes, namelijk de keys, en een string is veel simpeler. Maar zelfs dan is het geheugengebruik van de string vele malen kleiner.
Dit experiment laat nog iets zien: Hoe efficient de string in het geheugen wordt opgeslagen. De toename van het geheugengebruik na het maken van de lange string is amper groter dan de werkelijke lengte van de string.
Is het normaal dat PHP zo inefficient met arrays om gaat? Want als dat zo is, dan moet je vooral grote arrays gaan mijden.