Jorden er giftig - faldgruber i PHP

Tags:    php
<< < 12 > >>
Skrevet af Bruger #4683 @ 08.05.2008


Løkker

Løkker bliver brugt rigtig mange steder - og det forstår man godt. Løkker er en uundgåelig del af at programmere - i alle de sprog jeg har arbejdet med.
I PHP er der fire typer af løkker: while, do...while, for og foreach. Jeg bruger dem alle pånær do...while - jeg ved egentlig ikke hvorfor, men jeg har aldrig haft brug for det.

Når man laver en løkke, skal man fastsætte nogle betingelser som skal overholdes (være 1 eller boolean true) for at "komme ind" i løkken. Det er disse betingelser jeg vil se på her.

Se på koden herunder:
Fold kodeboks ind/udKode 


Der er fire stykker i koden herover, to for count() [2] og to for strlen() [3].
I to af eksemplerne ligger funktionskaldet inde i det inderste loop, mens det for de resterende to ligger lige uden for.
Resultater er vist herunder (figur 3), og den overordnede konklusion overrasker ikke.

figur 3


De viste værdier er fold over gennemsnittet af count() uden for loopet.

Som man ser, er det altså rundt regnet 2,5 gange langsommere at have et funktionskald inde i løkkebetingelsen som at placere det lige uden for.

Moralen er altså, at man bør afholde sig fra at lave funktionskald inde i betingelserne for en løkke.

Ud over at det er langsommere at have et funktionskald i en løkkebetingelse, er det også farligt...
Det er farligt i den forstand at selve løkken kan ændre det array (f.eks.) man har brugt i betingelsen. Et lille eksempel er vist herunder:

<?php
$array = array(1,2,3);
for ($i = 0; $i<count($array);$i++) {
$array[] = $i;
}
?>

Denne løkke vil køre i mere end 3 iterationer :)

Mere vil jeg ikke komme ind på løkker i denne artikel, men de viste eksempler burde give et indblik i hvordan løkker kan gøres bedre og mere sikre.


Arrays

Arrays i PHP er en af de absolut sejeste datatyper jeg har stødt på. Jeg har endnu ikke mødt en datatype som man ikke kan smide ind i et array (de findes måske, men praktisk har jeg aldrig stødt på dem).

I PHP findes utroligt mange funktioner til brug på arrays, hvilket betyder at du ikke selv skal sidde og lave langsomme funktioner i PHP. Mange af PHP's indbyggede funktioner er skrevet i C, hvilket gør dem ekstremt hurtige i forhold til funktioner skrevet i PHP.

Arrays er også en meget tilgivende datastruktur, og det er her muligheden for optimering ligger.

Se på koden herunder:

Fold kodeboks ind/udKode 


Jah, det er hård kost... I begge eksempler bruger jeg et array med følgende struktur: array("key" => "value") - det har altså en streng som key/index og en streng som værdi. Værdien er ikke så interessant i dette tilfælde, men det er arrayets key.

I det øverste eksempel sætter jeg $array[key] = $i - læg mærke til at jeg ikke angive key som en streng. Denne operation er virkelig grim, men PHP gør som vi beder den om, dog kommer den med en E_NOTICE fejl (hvorfor jeg har sat error_reporting til 1, da jeg ikke gider at sidde med 4.000.000 fejl på min skærm :) ). Desuden bliver der oprettet en streng "on the fly" som hedder "key".

Hvilken en af de to eksempler som er hurtigst fremgår herunder (figur 4):

figur 4




Afsluttende bemærkninger...

Det virker måske dumt, at skulle optimere noget så det tager 0,002 sek i stedet for 0,003 sek. Det har som regel ingen praktisk indflydelse...

Personligt synes jeg at der er mange grunde, men den største er vel: "hvor ikke?"
Der er jo ingen grund til, at skrive en masse kode som tager unødigt lang tid at eksekvere og som desuden kan være ophav til forskellige bugs.

I disse tider med stor fokus på global opvarming og CO2 udslip er det vel vores pligt, at spare på strømmen til servernes CPU'er :)

Der er også et aspekt af stolthed i det - hvorfor skrive grim kode? (pæn/grim kode er naturligvis subjektivt)





------------
[1]: http://dk.php.net/manual/en/function.microtime.php

[2]: http://dk.php.net/manual/en/function.count.php

[3]: http://dk.php.net/manual/en/function.strlen.php




<< < 12 > >>

Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (15)

User
Bruger #11328 @ 09.05.08 11:51
Super god artikel!
Fik rigtig mange ting ud af den, især det med at array keys (helst) skal være strenge. Jeg plejer altid selv at gøre det, fordi jeg synes at alt andet vil være bad habit, men det er dejligt at få bekræftet at man gør noget rigtigt! :)

Jeg synes dog lige at du i starten skulle forklare ord som "fold" o. lign. Og hvorfor du laver et så stort loop.
User
Bruger #3275 @ 09.05.08 20:02
Sjov artikel, jeg synes dog den er lidt kort, du kunne f.eks. have kommet ind på de forskellige måder man kan iterere over variabler på (for, foreach, while etc.).
User
Bruger #4683 @ 09.05.08 20:15

Sjov artikel, jeg synes dog den er lidt kort, du kunne f.eks. have kommet ind på de forskellige måder man kan iterere over variabler på (for, foreach, while etc.).


Det er korrekt, at der er mange andre ting man kan tage fat på ... Mit formål med artiklen var bare at skabe fokus på nogle af de muligheder der ligger for optimere (og pænere kode).

Artiklen er kort! Jeg var såmænd bare i tvivl om, om folk ville gide at læse en lang svale med det samme :)
User
Bruger #5620 @ 10.05.08 11:15
er da rart at kende måder man kan spare cpu tid på, men jeg er lidt imod den sidste. Du tester jo sådan set på om en korrekt måde at kode på er bedre end en decideret forkert måde, det jo en irrelevant test da man aldrig skal kode på den sidste måde uanset om den havde været hurtigere eller ej. En mere fornuftig test ville da have været forskellen mellem de 3 korrekte måder.

$array["key"]

$key=key;
$array[$key]

define("key","key");
$array[key]

evt. også forskellen på at bruge streng indekseret array i forhold til tal indekseret arrays, hvad er interresant da de
fleste jo bruger det første i gennemløb af mysql resultater.
User
Bruger #4683 @ 10.05.08 11:36
Den sidste test er en af mine "personlige" kæpheste :)

Det ses faktisk mange steder, også her på udvikleren:

http://www.udvikleren.dk/PHP/Thread.aspx/6/24692/

http://www.udvikleren.dk/PHP/Thread.aspx/6/24649/

...for bare at nævne 2


Jeg tog den netop med fordi det er en, ofte anvendt, grim/forkert måde at gøre det på :)
User
Bruger #4479 @ 10.05.08 19:46
God artikel! :)
User
Bruger #13702 @ 11.05.08 16:25
God - Jeg blev klogere :bounce:
User
Bruger #12836 @ 06.06.08 15:06


Hej JT,

Ganske velskrevet og humoristisk artikkel.

Jeg syntes dog ikke at indholdet var godt.

Kode eksemplerne som bliver taget op sammenligner fejlkode, som PHP's fortolker er modstandsdygtig overfor, med korrekt kode. Fjollet, specielt idet at folk vil lave fejlene, ikke vil forstå hvad fejlen er i den kode som er beskrevet.

Artiklen starter med at rose den feature som gør at de dårlige kodeeksempler ikke bare fejler?!

De 2 ovenstående ting gør at jeg har sat et midelmådigt 3 tal. Humoren, de korte forklaringer, den forstålige grafik og kode eksemplerne gør at den ikke er endnu lavere.

Mit forslag: Skrot artiklen og lav en begynder rettet artikkel om præcis det samme. Og skip lige al rosen om PHP's variabel forståelse. Det gør kode ulæselig og meget svær at vedligeholde, hvis man ikke sikrer type konsistens - udover at det gør koden langsommere.

I PHP er perfomance vigtigt, ja, selv til små projekter. Det mangler at blive pointeret at det er 0,01 sekund pr side som hver bruger ser. Og at det er Server load (og din online host One.com har mange).

Med venlig hilsen
Ieet
User
Bruger #4683 @ 06.06.08 16:01
Hej Ieet

Jeg tror måske at du har misforstået formålet med artiklen - eller også kommer der bare ikke klart frem.

Formålet er at vist nogle eksempler som bliver brugt ofte, rigtigt eller forkert - det hænger jeg mig ikke i. De "fejl" som beskrives her ses jo dagligt her på udvikleren :)


Artiklen starter med at rose den feature som gør at de dårlige kodeeksempler ikke bare fejler?!


Ja, nemlig! Pointen er, at hvis man kun skal lave noget een gang, så kan du ligeså godt bruge det faktum at PHP er typesvagt frem for at typecaste. Typesvaghed er jo ikke kun godt/dårligt. Personligt er jeg glad for det - hvis det bruges korrekt.

I C++ (blandt andre) skal man jo igennem en noget større omgang for at ændre type.



Kode eksemplerne som bliver taget op sammenligner fejlkode, som PHP's fortolker er modstandsdygtig overfor, med korrekt kode. Fjollet, specielt idet at folk vil lave fejlene, ikke vil forstå hvad fejlen er i den kode som er beskrevet.


Jeg synes nu ellers at jeg forklarer ganske præcist hvad "fejlen" er i hver kode :)


... Og skip lige al rosen om PHP's variabel forståelse. Det gør kode ulæselig og meget svær at vedligeholde, hvis man ikke sikrer type konsistens - udover at det gør koden langsommere.


Hmm... Jeg vil ikke skippe noget :) Til det PHP er lavet til, er det faktum at det er typesvagt stort set kun positivt.
User
Bruger #8985 @ 06.06.08 20:52
"Til det PHP er lavet til, er det faktum at det er typesvagt stort set kun positivt."

Det var en interessant kommentar. Hvad mener du selv, PHP er lavet til?
User
Bruger #4683 @ 06.06.08 23:33

"Til det PHP er lavet til, er det faktum at det er typesvagt stort set kun positivt."

Det var en interessant kommentar. Hvad mener du selv, PHP er lavet til?



For at citere php.net "PHP stands for PHP: Hypertext Preprocessor" og "PHP is an HTML-embedded scripting language".

Jeg har ikke sagt hvad det _kan_ bruges til...

Og som et HTML-embedded scripting language er det altså okay at være typesvagt - synes jeg :)
User
Bruger #4683 @ 06.06.08 23:47
altså....

Hvis man selv opretter en variabel er det godt at lave den i korrekt type.

Skal man bruge noget fra _GET, _POST, osv en enkelt gang, kan det ikke betale sig at typecaste den (det skulle da lige være i tilfælde hvor sikkerheden gør det til en god ide)

Skal man bruge noget fra _GET, _POST, osv mere end et par gange, så kan det godt betale sig at typecaste (hvis der skal laves operationer som logisk kræver en anden type).

Naturligvis skal man aldrig bruge forkert type som array-index...



User
Bruger #13869 @ 08.06.08 20:42
God artikel. :)

Selvom, jeg har læst nogle mere detaljerede på engelsk, rundt om kring. (Søg evt. på "optimize php scripts" på Google)
User
Bruger #12836 @ 10.06.08 15:48

Hej JT,

Jeg havde forstået formålet.

Uenigheden er, at selvom du og jeg godt kan se problemet i den PHP kode som er skrevet, og godt kan forstå dine forklaringer, er vi ikke målgruppen til artiklen (dem som ville kunne lave de beskrevne fejl).

Fejlene er ikke beskrevet dybdegående og forklarende nok til at folk som ville lave fejlene ville kunne forstå forklaringerne.

Med venlig hilsen
Ieet

User
Bruger #13723 @ 12.06.08 16:16
Var faktisk nogle små rare ting som er gode at vide :P
Du skal være logget ind for at skrive en kommentar.
t