Guide:
Optimering av websider
Når man lager nettsider, ender man av og til opp med sider som tar lang tid å laste. Her er noen tips for hvordan du kan unngå slike ting.
Unngå nestede løkker
Løkker i ulike former kan være et svært nyttig verktøy i mange sammenhenger, og om man bruker disse rett er de svært raske. Derimot er det lett for å lage strukturer slik at man må ha flere løkker inni hverandre, noe som kan være svært tregt. Et typisk eksempel på dette er følgende kodesnutt;
<?php
for ($i = 0; $i < count($array1); $i++)
{
for ($j = 0; $j < count($array2); $j++)
{
$array1[$i] += $array2[$j];
}
}
?>
Om du tester dette med tabeller som hver har under 100 verdier i seg, vil ikke det ta spesielt lang tid å kjøre denne kodesnutten. Derimot vil det ta svært lang tid dersom mengden verdier plutselig en dag blir tidoblet, da kjøretiden vil vokse kvadratisk.
Med 100 verdier i hver tabell vil du bare måtte gå gjennom 10 000 kjøringer av den innerste løkken. Med tusen verdier i hver tabell, stiger det tallet til en million. Med ti tusen verdier i hver tabell må man gjennom den innerste delen av koden hundre millioner ganger.
Det er svært få problemer som krever at du faktisk benytter deg av to løkker inne i hverandre, og svært mange slike problemer kan omskrives. Løsningen ovenfor kan skrives om på flere forskjellige måter, den første er med en enkel løkke;
<?php
$sumArray2 = array_sum($array2);
for ($i = 0; $i < count($array1); $i++)
{
$array1[$i] += $sumArray2;
}
?>
Dersom du har lyst til å skrive kode som kan være litt mindre leselig, men gjør akkurat det samme, kan du også skrive det slik som under. Legg merke til at selv om du på denne måten ikke skriver en for-løkke eksplisitt i programmet ditt, vil array_map-metoden oversette dette til en for-løkke internt.
<?php
$sumArray2 = array_sum($array2);
function add($n)
{
global $sumArray2;
return $n + $sumArray2;
}
$array1 = array_map("add", $array1);
?>
Vi testet å kjøre disse forskjellige variantene av den samme koden på to tabeller som hver inneholdt 1000 verdier, og vi målte tiden det tok å kjøre koden 1000 ganger. Den første koden ble ikke ferdig innen 30-sekundersgrensen som PHP legger på kjøringen av skript, mens de to neste ble ferdig på henholdsvis 1.5 og 3.9 sekunder.
Legg merke til at bruken av array_map alltid er tregere enn en enkelt for-løkke. array_map er en funksjon som er hentet fra deklarativ programmering, hvor man normalt ikke har løkker på samme måten som i PHP.
Unntak
Doble løkker er ikke nødvendigvis alltid farlig. Dersom du vet at den ytterste løkken aldri kjører mer enn 30 ganger; f.eks. dersom du henter ut 30 rader fra en database. Om du samtidig vet at den innerste løkken også aldri kjører mer enn et visst antall ganger, vil du til en viss grad være trygg.
Derimot, dersom du kan erstatte doble løkker med en enkel løkke, eller to enkle løkker på samme nivå, vil du i lengden spare mye prosessorkraft.