Оптимизация на ненужни масиви в PHP
Нека пред един програмист стои задачата
да намери сумата на целите числа от 1 до 100000000.
Нашият програмист направи елегантно решение на тази задача, ето така:
<?php
echo array_sum(range(1, 100000000));
?>
Хубаво решение, нали? На един ред и всичко това. Но то не работи! Опитайте се да стартирате този код и той ще изведе на екрана грешка, че сте поискали твърде много оперативна памет.
Хм, 100000000 изглежда не е толкова много?
Или е много? Нека пресметнем. Функцията range
създава масив с 100000000 числа.
Нека PHP заделя за число 2 байта
- тогава за съхранението на нашия масив ще са необходими
200000000 байта, тоест нещо около
200 мегабайта оперативна памет.
Но всъщност ще е необходима много повече
оперативна пама, защото в PHP има много
големи режийни разходи при съхранението на масив.
Например, при мен в текста на грешката се изписва,
че се опитвам да заделя 4294967304
байта - нещо около 4 гигабайта!
Ясно вече защо се появява грешка - ние далеч надхвърлихме разрешения лимит на паметта.
Не е толкова трудно да пренапишем нашия скрипт по друг начин, почти без да консумира оперативна памет:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
А още по-добре използваме математическо решение:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Пред един програмист стои задачата да намери факториела на дадено число. Той я реши по следния начин:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Обяснете какво не е наред с този код. Преправете кода на по-оптимален.
Пред един програмист стои задачата да намери
броя на цифрите, с които могат да бъдат
записани всички цели числа от 1 до 1000000.
Той я реши по следния начин:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Обяснете какво не е наред с този код. Преправете кода на по-оптимален.
Пред един програмист стои задачата да намери
броя на числата, които се делят без остатък на
7, намиращи се в даден
интервал. Той я реши по следния начин:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Обяснете какво не е наред с този код. Преправете кода на по-оптимален.
Пред един програмист стои задачата да намери сумата на делителите на число. Той я реши по следния начин:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Обяснете какво не е наред с този код. Преправете кода на по-оптимален.