Аптымізацыя непатрэбных масіваў у 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);
?>
Тлумачце, што не так з гэтым кодам. Перарабіце код на больш аптымальны.