Optimizarea array-urilor inutile în PHP
Să presupunem că un programator are sarcina
de a găsi suma numerelor întregi de la 1 la 100000000.
Programatorul nostru a scris o soluție elegantă la această sarcină, astfel:
<?php
echo array_sum(range(1, 100000000));
?>
Soluție frumoasă, nu-i așa? Doar o linie și toate astea. Dar nu funcționează! Încercați să rulați acest cod și va afișa o eroare despre faptul că ați solicitat prea multă memorie.
Hmm, 100000000 nu pare atât de mult?
Sau este mult? Să calculăm. Funcția range
creează un array cu 100000000 numere.
Să presupunem că PHP alocă 2 octeți
pentru un număr - atunci pentru stocarea array-ului nostru va fi nevoie de
200000000 octeți, adică aproximativ
200 megabyți de memorie.
Dar, în realitate, va fi necesară mult mai multă memorie
datorită faptului că PHP are
foarte mari costuri suplimentare la stocarea array-urilor.
De exemplu, în textul erorii mie îmi spune
că încerc să aloc 4294967304
octeți - adică aproximativ 4 gigabyți!
Este clar acum de ce apare eroarea - am depășit cu mult limita de memorie permisă.
Nu este atât de dificil să rescriem scriptul nostru într-un alt mod, practic fără a consuma memorie:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Și mai bine este să folosim soluția matematică:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Un programator a avut sarcina de a găsi factorialul unui număr dat. El a rezolvat-o în felul următor:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Explicați ce nu este în regulă cu acest cod. Rescrieți codul într-o variantă mai optimă.
Un programator a avut sarcina de a găsi
numărul de cifre cu care se pot
scrie toate numerele întregi de la 1 la 1000000.
El a rezolvat-o în felul următor:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Explicați ce nu este în regulă cu acest cod. Rescrieți codul într-o variantă mai optimă.
Un programator a avut sarcina de a găsi
numărul de numere divizibile fără rest la
7, aflate într-un
interval dat. El a rezolvat-o în felul următor:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Explicați ce nu este în regulă cu acest cod. Rescrieți codul într-o variantă mai optimă.
Un programator a avut sarcina de a găsi suma divizorilor unui număr. El a rezolvat-o în felul următor:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Explicați ce nu este în regulă cu acest cod. Rescrieți codul într-o variantă mai optimă.