Nevajadzīgu masīvu optimizācija PHP
Pieņemsim, ka kādam programmētājam ir uzdevums
atrast veselu skaitļu summu no 1 līdz 100000000.
Mūsu programmētājs uzrakstīja elegantu šī uzdevuma risinājumu, šādi:
<?php
echo array_sum(range(1, 100000000));
?>
Skaists risinājums, vai ne? Vienā rindiņā un tas arī viss. Bet tas nedarbojas! Mēģiniet palaist šo kodu, un tas izmetīs ekrānā kļūdu par to, ka esat pieprasījis pārāk daudz operatīvās atmiņas.
Hmm, 100000000 it kā nav tik daudz?
Vai tomēr daudz? Skaitīsim. Funkcija range
izveido masīvu ar 100000000 skaitļiem.
Pieņemsim, ka PHP atvēl 2 baitus
uz vienu skaitli - tad mūsu masīva glabāšanai būs nepieciešami
200000000 baiti, tas ir, aptuveni
200 megabaiti operatīvās atmiņas.
Bet patiesībā operatīvās atmiņas būs nepieciešams
daudz vairāk tāpēc, ka PHP ir ļoti
lieli pieskaitāmie izdevumi, glabājot masīvu.
Piemēram, man kļūdas tekstā norādīts,
ka es mēģinu piešķirt 4294967304
baitus - tas ir kaut kas ap 4 gigabaitiem!
Tagad saprotams, kāpēc izlido kļūda - mēs esam tālu pārsnieguši atļauto atmiņas limitu.
Nav tik grūti pārrakstīt mūsu skriptu citā veidā, kas praktiski nepatērē operatīvo atmiņu:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Vai vēl labāk izmantosim matemātisko risinājumu:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Kādam programmētājam bija uzdevums atrast dotā skaitļa faktoriāli. Viņš to atrisināja šādi:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Paskaidrojiet, kas šajā kodā nav kārtībā. Pārveidojiet kodu uz optimālāku.
Kādam programmētājam bija uzdevums atrast
ciparu skaitu, ar kuru var
uzrakstīt visus veselos skaitļus no 1 līdz 1000000.
Viņš to atrisināja šādi:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Paskaidrojiet, kas šajā kodā nav kārtībā. Pārveidojiet kodu uz optimālāku.
Kādam programmētājam bija uzdevums atrast
skaitļu skaitu, kas dalās bez atlikuma ar
7, atrodoties noteiktā
intervālā. Viņš to atrisināja šādi:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Paskaidrojiet, kas šajā kodā nav kārtībā. Pārveidojiet kodu uz optimālāku.
Kādam programmētājam bija uzdevums atrast skaitļa dalītāju summu. Viņš to atrisināja šādi:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Paskaidrojiet, kas šajā kodā nav kārtībā. Pārveidojiet kodu uz optimālāku.