PHP mittevajalike massiivide optimeerimine
Oletame, et ühele programmeerijale seati ülesandeks
leida täisarvude summa vahemikus 1 kuni 100000000.
Meie programmeerija kirjutas selle ülesande jaoks elegantse lahenduse, mis näeb välja selline:
<?php
echo array_sum(range(1, 100000000));
?>
Ilus lahendus, kas pole? Ühes reas ja kõik. Kuid see ei tööta! Proovige seda koodi käivitada ja see kuvab veateate, et taotlete liiga palju mälu.
Hmm, 100000000 ei tundu nagu nii palju?
Või on siiski? Arvutame. Funktsioon range
loob massiivi 100000000 numbriga.
Oletame, et PHP eraldab numbri kohta 2 baiti
- siis meie massiivi hoidmiseks on vaja
200000000 baiti, see tähendab umbes
200 megabaiti operatiivmälu.
Tegelikult vajab operatiivmälu palju rohkem,
kuna PHP-l on massiivide hoidmisel väga
suured üldkulud. Näiteks minu veatekstis öeldakse,
et üritan eraldada 4294967304
baiti - see on umbes 4 gigabaiti!
Nüüd on selge, miks ilmub viga - oleme lubatud mälupiirangust kaugelt üle läinud.
Pole nii raske kirjutada meie skript ümber teiseks, mis praktiliselt ei tarbi operatiivmälu:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Või veel parem, kasutame matemaatilist lahendust:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Ühele programmeerijale seati ülesandeks leida antud arvu faktoriaal. Ta lahendas selle järgmiselt:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Selgitage, mis selle koodiga valesti on. Kirjutage kood ümber optimeeritumaks.
Ühele programmeerijale seati ülesandeks leida
numbrite arv, mida kasutades saab kirjutada
kõik täisarvud vahemikus 1 kuni 1000000.
Ta lahendas selle järgmiselt:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Selgitage, mis selle koodiga valesti on. Kirjutage kood ümber optimeeritumaks.
Ühele programmeerijale seati ülesandeks leida
arvude arv, mis jaguvad ilma jäägita
7-ga, asuvad antud
vahemikus. Ta lahendas selle järgmiselt:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Selgitage, mis selle koodiga valesti on. Kirjutage kood ümber optimeeritumaks.
Ühele programmeerijale seati ülesandeks leida arvu jagajate summa. Ta lahendas selle järgmisel viisil:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Selgitage, mis selle koodiga valesti on. Kirjutage kood ümber optimeeritumaks.