Optimizacija nepotrebnih polj v PHP
Naj ima nek programer nalogo
poiskati vsoto celih števil od 1 do 100000000.
Naš programer je napisal elegantno rešitev te naloge, takole:
<?php
echo array_sum(range(1, 100000000));
?>
Lepa rešitev, ali ne? V eni vrstici in vse to. Vendar ne deluje! Poskusite zagnati to kodo in pokazala vam bo napako o tem, da ste zahtevali preveč delovnega pomnilnika.
Hm, 100000000 ni videti tako veliko?
Ali pa je? Preštejmo. Funkcija range
ustvari polje z 100000000 števili.
Naj PHP dodeli za število 2 bajta
- potem bo za shranjevanje našega polja potrebno
200000000 bajtov, torej približno
200 megabajtov delovnega pomnilnika.
Toda v resnici bo potrebno veliko več
delovnega pomnilnika zaradi tega, ker ima PHP zelo
velike režijske stroške pri shranjevanju polja.
Na primer, pri meni v besedilu napake piše,
da poskušam dodeliti 4294967304
bajtov - kar je približno 4 gigabajtov!
Zdaj je jasno, zakaj se pojavi napaka - daleč smo presegli dovoljeno mejo pomnilnika.
Ni tako težko prepisati naš skript v drugega, ki praktično ne porabi delovnega pomnilnika:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Še bolje je uporabiti matematično rešitev:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Nek programer je imel nalogo poiskati fakulteto danega števila. Rešil jo je na naslednji način:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.
Nek programer je imel nalogo poiskati
število števk, s katerimi lahko
zapišemo vsa cela števila od 1 do 1000000.
Rešil jo je na naslednji način:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.
Nek programer je imel nalogo poiskati
število števil, deljivih brez ostanka z
7, ki se nahajajo v danem
intervalu. Rešil jo je na naslednji način:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.
Nek programer je imel nalogo poiskati vsoto deliteljev števila. Rešil jo je na naslednji način:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.