Optimalizácia nepotrebných polí v PHP
Predpokladajme, že programátor má za úlohu
nájdenie súčtu celých čísel od 1 do 100000000.
Naš programátor napísal elegantné riešenie tejto úlohy, takto:
<?php
echo array_sum(range(1, 100000000));
?>
Krásne riešenie, nie? V jednom riadku a tak ďalej. Ale nie je funkčné! Skúste spustiť tento kód a vypíše chybu o tom, že ste požadovali príliš veľa operačnej pamäte.
Hm, 100000000 nie je zdá sa až tak veľa?
Alebo je? Počítajme. Funkcia range
vytvára pole s 100000000 číslami.
Predpokladajme, že PHP alokuje na číslo 2 bajty
- potom na uloženie nášho poľa bude potrebných
200000000 bajtov, teda približne
200 megabajtov operačnej pamäte.
Ale v skutočnosti bude potrebná oveľa väčšia
operačná pamäť kvôli tomu, že PHP má veľmi
veľké režijné náklady pri ukladaní poľa.
Napríklad, u mňa v texte chyby sa uvádza,
že sa pokúšam alokovať 4294967304
bajtov - čo je približne 4 gigabajty!
Je teraz jasné, prečo nastáva chyba - vyšli sme ďaleko za povolený limit pamäte.
Nie je tak ťažké prepísať náš skript na iný, takmer nespotrebúvajúci operačnú pamäť:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
A ešte lepšie je použiť matematické riešenie:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Pred niektorým programátorom stála úloha nájsť faktoriál daného čísla. Vyriešil ju nasledovne:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Vysvetlite, čo je nesprávne na tomto kóde. Prepíšte kód na optimalizovanejší.
Pred niektorým programátorom stála úloha nájsť
počet číslic, ktorými možno
zapísať všetky celé čísla od 1 do 1000000.
Vyriešil ju nasledovne:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Vysvetlite, čo je nesprávne na tomto kóde. Prepíšte kód na optimalizovanejší.
Pred niektorým programátorom stála úloha nájsť
počet čísel deliteľných bezo zvyšku
7, nachádzajúcich sa v danom
intervale. Vyriešil ju nasledovne:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Vysvetlite, čo je nesprávne na tomto kóde. Prepíšte kód na optimalizovanejší.
Pred niektorým programátorom stála úloha nájsť súčet deliteľov čísla. Vyriešil ju nasledovne:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Vysvetlite, čo je nesprávne na tomto kóde. Prepíšte kód na optimalizovanejší.