Tarpeettomien taulukoiden optimointi PHP:ssä
Oletetaan, että ohjelmoijalla on tehtävänä
löytää kokonaislukujen summa 1:stä 100000000:aan.
Ohjelmoijamme kirjoitti tyylikkään ratkaisun tähän tehtävään, näin:
<?php
echo array_sum(range(1, 100000000));
?>
Kaunis ratkaisu, eikö olekin? Yhdellä rivillä ja kaikkea sellaista. Mutta se ei toimi! Yritä ajaa tämä koodi ja se tulostaa näytölle virheen siitä, että pyysit liian paljon keskusmuistia.
Hmm, 100000000 ei vaikuta kovin suurelta?
Vai onko? Lasketaan. Funktio range
luo taulukon, jossa on 100000000 numeroa.
Oletetaan, että PHP varaa numerolle 2 tavua
- tällöin taulukkomme tallentamiseen tarvitaan
200000000 tavua, eli noin
200 megatavua keskusmuistia.
Mutta todellisuudessa keskusmuistia tarvitaan
paljon enemmän, koska PHP:ssä on erittäin
suuret yleiskustannukset taulukon tallennuksessa.
Esimerkiksi minulla virhetiedossa sanotaan,
että yritän varata 4294967304
tavua - noin 4 gigatavua!
Ymmärrätte nyt, miksi virhe tulee - olemme ylittäneet sallitun muistirajan.
Ei ole kovin vaikeaa kirjoittaa koodimme uudelleen toisella, käytännössä keskusmuistia kuluttamattomalla tavalla:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Tai vielä parempi, käytetään matemaattista ratkaisua:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Erään ohjelmoijan tehtävänä oli löytää annetun luvun kertoma. Hän ratkaisi sen seuraavasti:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Selitä, mikä tässä koodissa on vialla. Muokkaa koodi optimaalisemmaksi.
Erään ohjelmoijan tehtävänä oli löytää
numeroiden määrä, joilla voidaan
kirjoittaa kaikki kokonaisluvut 1:stä 1000000:aan.
Hän ratkaisi sen seuraavasti:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Selitä, mikä tässä koodissa on vialla. Muokkaa koodi optimaalisemmaksi.
Erään ohjelmoijan tehtävänä oli löytää
niiden lukujen määrä, jotka ovat jaollisia
7:llä ilman jäännöstä, annetulla
välillä. Hän ratkaisi sen seuraavasti:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Selitä, mikä tässä koodissa on vialla. Muokkaa koodi optimaalisemmaksi.
Erään ohjelmoijan tehtävänä oli löytää luvun tekijöiden summa. Hän ratkaisi sen seuraavasti:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Selitä, mikä tässä koodissa on vialla. Muokkaa koodi optimaalisemmaksi.