Optymalizacja niepotrzebnych tablic w PHP
Załóżmy, że pewien programista ma zadanie
znaleźć sumę liczb całkowitych od 1 do 100000000.
Nasz programista napisał eleganckie rozwiązanie tego zadania, o tak:
<?php
echo array_sum(range(1, 100000000));
?>
Piękne rozwiązanie, prawda? W jednej linii i tak dalej. Ale ono nie działa! Spróbuj uruchomić ten kod, a wyświetli się błąd o tym, że zażądałeś zbyt dużej ilości pamięci operacyjnej.
Hmm, 100000000 wydaje się nie tak dużo?
Czy może dużo? Policzmy. Funkcja range
tworzy tablicę z 100000000 liczbami.
Załóżmy, że PHP przydziela na liczbę 2 bajty
- wtedy do przechowania naszej tablicy będzie potrzebne
200000000 bajtów, czyli około
200 megabajtów pamięci operacyjnej.
Ale w rzeczywistości potrzeba będzie
znacznie więcej pamięci operacyjnej
z powodu bardzo dużych narzutów w PHP
przy przechowywaniu tablicy.
Na przykład, u mnie w tekście błędu wyświetla się,
że próbuję przydzielić 4294967304
bajtów - około 4 gigabajtów!
Teraz jasne jest, dlaczego wyskakuje błąd - znacznie przekroczyliśmy dozwolony limit pamięci.
Nie jest trudno przepisać nasz skrypt na inny, praktycznie nie zużywający pamięci operacyjnej:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
A jeszcze lepiej użyjmy matematycznego rozwiązania:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Pewien programista miał zadanie znaleźć silnię podanej liczby. Rozwiązał je w następujący sposób:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Wyjaśnij, co jest nie tak z tym kodem. Przerób kod na bardziej optymalny.
Pewien programista miał zadanie znaleźć
liczbę cyfr, za pomocą których można
zapisać wszystkie liczby całkowite od 1 do 1000000.
Rozwiązał je w następujący sposób:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Wyjaśnij, co jest nie tak z tym kodem. Przerób kod na bardziej optymalny.
Pewien programista miał zadanie znaleźć
liczbę liczb podzielnych bez reszty przez
7, znajdujących się w podanym
przedziale. Rozwiązał je w następujący sposób:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Wyjaśnij, co jest nie tak z tym kodem. Przerób kod na bardziej optymalny.
Pewien programista miał zadanie znaleźć sumę dzielników liczby. Rozwiązał je w następujący sposób:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Wyjaśnij, co jest nie tak z tym kodem. Przerób kod na bardziej optymalny.