Discussion:
Kan denne løkke optimeres?
(for gammel til at besvare)
Bertel Lund Hansen
2013-05-16 10:14:23 UTC
Permalink
Hej allesammen

Jeg har en løkke i PHP, men problemstillingen er helt generel.
Den drejer sig om at jeg i andre løkker gennem et array skal
kunne konstatere om vi har med en given overskrift (head) at
gøre. Jeg løser problemet ved at gennemløbe mit grundarray med
overskrifter og så sammenligne hver gang med en konstant der er
defineret i forvejen. $nr holder rede på hvilket tal vi er kommet
til (det er en enumerator).

foreach ($headers as $nr => $head) {
if ($head==TYPEHEAD) $typenr=$nr;
if ($head==SQMPHEAD) $sqmpnr=$nr;
if ($head==TIMEHEAD) $timenr=$nr;
if ($head==ENGYHEAD) $nrgynr=$nr;
if ($head==FLORHEAD) $flornr=$nr;
if ($head==DISTHEAD) $distnr=$nr;
if ($head==SCORHEAD) $scornr=$nr;
}

Konstanterne er angivet i den rækkefølge de har i arrayet
$headers. Det sikrer at jeg kun behøver ét gennemløb.

Jeg er åben overfor andre forslag til at løse det egentlige
problem, men det er nok vanskeligt på de foreliggende oplysninger
at se andre muligheder. Men jeg prøver lige med noget
eksempelkode:

function check_values ($infoarray) {
$val1 = $infoarray[$typenr];
$val2 = $infoarray[$nrgynr];
return $val1<$limit && $val2>$minimum;
}

function format ($infoarray) {
foreach ($infoarray as $nr => $value) {
if ($nr==$timenr) dateformat($value);
if ($nr==$scornr) numberformat($value);
...
}
}

De viser hvordan jeg bruger de fundne nummerværdier i selve
kodedelen.
--
Bertel
http://bertel.lundhansen.dk/ http://fiduso.dk/
Peter Makholm
2013-05-16 11:59:51 UTC
Permalink
Post by Bertel Lund Hansen
foreach ($headers as $nr => $head) {
if ($head==TYPEHEAD) $typenr=$nr;
if ($head==SQMPHEAD) $sqmpnr=$nr;
if ($head==TIMEHEAD) $timenr=$nr;
if ($head==ENGYHEAD) $nrgynr=$nr;
if ($head==FLORHEAD) $flornr=$nr;
if ($head==DISTHEAD) $distnr=$nr;
if ($head==SCORHEAD) $scornr=$nr;
}
De to optimeringer jeg umidelbart lige kan få øje på er enten at tilføje
nogle continue-udtryk eller at skrive det om til et
switch-udtryk. Performance-mæssigt vil jeg nok anse begge dele for
mikrooptimeringer, men mindre du har benchmarks der viser at der bruges
meget tid i netop dette stykke kode.

En moderne oversætter bør være ligeglad med hvilken af mulighederne du
vælger, men for en dum oversætter ville jeg bruge et switch-udtryk. Det
er nok også mere idiomatisk, hvilket også er en god grund til at lave
ændringen.


En helt anden mulighed er at bruge array_flip() der bytter om på nøgler
og værdier. Så har du noget ala:

$mapping = array_flip($headers);

function check_values ($infoarray) {
$val1 = $infoarray[ $mapping[TYPEHEAD] ];
$val2 = $infoarray[ $mapping[ENGYHEAD] ];

return $val1 < $limit && $val2 > $minimum;
}

Det gør selvfølgelig chack_values() en lille smule dyrere. Men det vil
jeg tro at til at overse, men mindre det virkelig er en flaskehals.


Vær opmærksom på om din kode giver det forventede resultat hvis en af
headerne optræder flere gange. Af hvad jeg kan læse mig til i
dokumationen vil array_flip() og din kode give sammenlignelige
resultater.

//Makholm
Bertel Lund Hansen
2013-05-16 12:55:49 UTC
Permalink
Post by Peter Makholm
De to optimeringer jeg umidelbart lige kan få øje på er enten at tilføje
nogle continue-udtryk eller at skrive det om til et
switch-udtryk. Performance-mæssigt vil jeg nok anse begge dele for
mikrooptimeringer, men mindre du har benchmarks der viser at der bruges
meget tid i netop dette stykke kode.
Tak for alle dine kommentarer. Det er nogle gode ideer.
Umiddelbart er switch oplagt - jeg burde faktisk have lavet det
fra starten af.

Jeg vil kikke på array_flip. Det er også en mulighed.
--
Bertel
http://bertel.lundhansen.dk/ http://fiduso.dk/
Loading...