Оптимизация ненужных массивов в 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);
?>
Объясните, что не так с этим кодом. Переделайте код на более оптимальный.