Optimizacija nepotrebnih nizova u PHP
Neka pred nekim programerom stoji zadatak
da pronađe sumu celih brojeva od 1 do 100000000.
Naš programer je napisao elegantno rešenje ove zadatke, ovako:
<?php
echo array_sum(range(1, 100000000));
?>
Lepo rešenje, zar ne? U jednu liniju i sve to. Ali ono ne radi! Pokušajte pokrenuti ovaj kod i on će prikazati grešku da ste zatražili previše operativne memorije.
Hm, 100000000 kao da nije tako mnogo?
Ili jeste? Hajde da izračunamo. Funkcija range
kreira niz sa 100000000 brojeva.
Neka PHP alocira 2 bajta
za svaki broj
- onda će za skladištenje našeg niza biti potrebno
200000000 bajta, odnosno oko
200 megabajta operativne memorije.
Ali zapravo biće potrebno mnogo više
operativne memorije zbog toga što PHP ima vrlo
visoke dodatne troškove prilikom skladištenja niza.
Na primer, u mom tekstu greške piše
da pokušavam da alociram 4294967304
bajta - što je oko 4 gigabajta!
Sada je jasno zašto se pojavljuje greška - daleko smo premašili dozvoljeni limit memorije.
Nije tako teško prepisati naš skript u drugi, koji praktično neće trošiti operativnu memoriju:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
A još bolje je da iskoristimo matematičko rešenje:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Pred nekim programerom je stajao zadatak da pronađe faktorijel datog broja. Rešio ga je na sledeći način:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Objasnite, šta nije u redu sa ovim kodom. Prepravite kod na optimalniji.
Pred nekim programerom je stajao zadatak da pronađe
broj cifara pomoću kojih se mogu
zapisati svi celi brojevi od 1 do 1000000.
Rešio ga je na sledeći način:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Objasnite, šta nije u redu sa ovim kodom. Prepravite kod na optimalniji.
Pred nekim programerom je stajao zadatak da pronađe
broj brojeva koji se dele bez ostatka sa
7, i koji se nalaze u datom
intervalu. Rešio ga je na sledeći način:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Objasnite, šta nije u redu sa ovim kodom. Prepravite kod na optimalniji.
Pred nekim programerom je stajao zadatak da pronađe zbir delilaca broja. Rešio ga je na sledeći način:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Objasnite, šta nije u redu sa ovim kodom. Prepravite kod na optimalniji.