⊗ppSpOtAU 94 of 95 menu

Optimalizace zbytečných polí v PHP

Předpokládejme, že programátor má za úkol najít součet celých čísel od 1 do 100000000.

Náš programátor napsal elegantní řešení této úlohy, takto:

<?php echo array_sum(range(1, 100000000)); ?>

Krásné řešení, že? Na jeden řádek a tak dále. Ale nefunguje! Zkuste spustit tento kód a vypíše chybu o tom, že jste požadovali příliš mnoho operační paměti.

Hmm, 100000000 není tak moc? Nebo je? Počítejme. Funkce range vytváří pole s 100000000 čísly. Předpokládejme, že PHP alokuje na číslo 2 bajty - pak pro uložení našeho pole bude potřeba 200000000 bajtů, tedy asi 200 megabajtů operační paměti.

Ve skutečnosti bude potřeba mnohem více operační paměti kvůli tomu, že PHP má velmi velké režijní náklady při ukládání pole. Například u mě text chyby uvádí, že se snažím alokovat 4294967304 bajtů - to je asi 4 gigabajty!

Je nyní jasné, proč vyhazuje chybu - výrazně jsme překročili povolený limit paměti.

Není tak těžké přepsat náš skript na jiný, téměř nespotřebovávající operační paměť:

<?php $sum = 0; for ($i = 1; $i <= 100000000; $i++) { $sum += $i; } echo $sum; ?>

A ještě lépe použijeme matematické řešení:

<?php $n = 1000000; $sum = $n * ($n + 1) / 2; echo $sum; ?>

Programátor měl za úkol najít faktoriál zadaného čísla. Vyřešil to následovně:

<?php $n = 100; echo array_product(range(1, $n)); ?>

Vysvětlete, co je na tomto kódu špatně. Přepište kód na optimalizovanější.

Programátor měl za úkol najít počet číslic, pomocí kterých lze zapsat všechna celá čísla od 1 do 1000000. Vyřešil to následovně:

<?php echo strlen(implode('', range(1, 1000000))); ?>

Vysvětlete, co je na tomto kódu špatně. Přepište kód na optimalizovanější.

Programátor měl za úkol najít počet čísel dělitelných beze zbytku 7, nacházejících se v zadaném intervalu. Vyřešil to následovně:

<?php $arr = []; for ($i = 0; $i <= 1000; $i++) { if ($i % 7 == 0) { $arr[] = $i; } } echo count($arr); ?>

Vysvětlete, co je na tomto kódu špatně. Přepište kód na optimalizovanější.

Programátor měl za úkol najít součet dělitelů čísla. Vyřešil to následujícím způsobem:

<?php $num = 320; $divs = []; for ($i = 0; $i <= $num; $i++) { if ($num % $i == 0) { $divs[] = $i; } } echo array_sum($divs); ?>

Vysvětlete, co je na tomto kódu špatně. Přepište kód na optimalizovanější.

deidkkuzpl