Оптимизација непотребних низова у 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);
?>
Објасните шта није у реду са овим кодом. Прерадите код у оптималнији.