Optimering af unødvendige arrays i PHP
Lad os sige, at en programmør står over for opgaven
at finde summen af heltal fra 1 til 100000000.
Vores programmør skrev en elegant løsning på denne opgave, sådan her:
<?php
echo array_sum(range(1, 100000000));
?>
En smuk løsning, er den ikke? På én linje og alt det der. Men den virker ikke! Prøv at køre denne kode, og den vil vise en fejl om, at du har anmodet om for meget RAM.
Hmm, 100000000 synes ikke at være så meget?
Eller er det? Lad os regne. Funktionen range
opretter et array med 100000000 tal.
Lad os sige, at PHP allokerer 2 bytes
per tal - så til opbevaring af vores array vil det kræve
200000000 bytes, det vil sige omkring
200 megabyte RAM.
Men faktisk vil det kræve meget mere RAM
på grund af, at PHP har meget
store omkostninger ved lagring af arrays.
For eksempel viser fejlteksten hos mig,
at jeg forsøger at allokere 4294967304
bytes - det er omkring 4 gigabyte!
Det er nu klart, hvorfor fejlen opstår - vi har langt overskredet den tilladte grænse for hukommelse.
Det er ikke så svært at omskrive vores script til et andet, der næsten ikke forbruger RAM:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Eller endnu bedre bruger vi en matematisk løsning:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
En programmør stod over for opgaven at finde fakultet af et givet tal. Han løste det på følgende måde:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Forklar, hvad der er galt med denne kode. Omskriv koden til en mere optimal version.
En programmør stod over for opgaven at finde
antallet af cifre, der kan bruges til at
skrive alle heltal fra 1 til 1000000.
Han løste det på følgende måde:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Forklar, hvad der er galt med denne kode. Omskriv koden til en mere optimal version.
En programmør stod over for opgaven at finde
antallet af tal, der er delelige uden rest med
7, inden for et givet
interval. Han løste det på følgende måde:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Forklar, hvad der er galt med denne kode. Omskriv koden til en mere optimal version.
En programmør stod over for opgaven at finde summen af divisors for et tal. Han løste det på følgende måde:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Forklar, hvad der er galt med denne kode. Omskriv koden til en mere optimal version.