PHP nereikalingų masyvų optimizavimas
Tarkime, prieš tam tikrą programuotoją yra užduotis
rasti sveikųjų skaičių sumą nuo 1 iki 100000000.
Mūsų programuotojas parašė elegantišką šios užduoties sprendimą, štai taip:
<?php
echo array_sum(range(1, 100000000));
?>
Gražus sprendimas, ar ne? Vienoje eilutėje ir viskas. Bet jis neveikia! Pabandykite paleisti šį kodą ir jis išmestų į ekraną klaidą apie tai, kad užsakėte per daug operatyviosios atminties.
Hm, 100000000 atrodo nėra labai daug?
Ar daug? Paskaičiuokime. Funkcija range
sukuria masyvą su 100000000 skaičių.
Tarkime, PHP skiria vienam skaičiui 2 baitus
- tada mūsų masyvui laikyti prireiks
200000000 baitų, tai yra maždaug
200 megabaitų operatyviosios atminties.
Bet iš tikrųjų operatyviosios atminties prireiks
žymiai daugiau dėl to, kad PHP turi labai
didelę pridėtinę kainą saugant masyvą.
Pavyzdžiui, mano tekste klaida rodo,
kad bandau paskirstyti 4294967304
baitus - maždaug 4 gigabaitus!
Dabar aišku, kodėl iškyla klaida - mes gerokai išėjome už leistinos atminties limito.
Ne taip sunku perrašyti mūsų scenarijų kitu, praktiškai nenaudojančiu operatyviosios atminties:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Arba dar geriau panaudokime matematinį sprendimą:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Prieš tam tikrą programuotoją buvo užduotis rasti duoto skaičiaus faktorialą. Jis ją išsprendė taip:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Paaiškinkite, kas negerai su šiuo kodu. Perdarykite kodą į optimalesnį.
Prieš tam tikrą programuotoją buvo užduotis rasti
skaitmenų kiekį, kuriais galima
užrašyti visus sveikuosius skaičius nuo 1 iki 1000000.
Jis ją išsprendė taip:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Paaiškinkite, kas negerai su šiuo kodu. Perdarykite kodą į optimalesnį.
Prieš tam tikrą programuotoją buvo užduotis rasti
skaičių, kurie be liekanos dalijasi iš
7, esančių tam tikrame
intervale. Jis ją išsprendė taip:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Paaiškinkite, kas negerai su šiuo kodu. Perdarykite kodą į optimalesnį.
Prieš tam tikrą programuotoją buvo užduotis rasti skaičiaus daliklių sumą. Jis ją išsprendė taip:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Paaiškinkite, kas negerai su šiuo kodu. Perdarykite kodą į optimalesnį.