Jorden er giftig - faldgruber i PHP

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

Som i alle andre programmeringssprog er PHP er sprog, hvor en given opgave kan løses på mange forskellige måder. Muligheden for selv at skræddersy en løsning er noget af det, som mange sikkert finde interessant og udfordrende ved at programmere - inklusive mig selv.

Selvom der er mange forskellige løsningsmodeller, givet det samme problem, er ikke alle lige anvendelige når det kommer til områder som skalerbarhed, sikkerhed, hastighed, osv.

I denne artikel har jeg valgt at fokusere på hastighed.
Hastighed er et område, som ikke får meget opmærksomhed før det er for sent. Det kan betyde at man skal til at udvikle en ny løsning for at afhjælpe en flaskehals på et live site.
Øget hastighed kan opnås gennem mange veje, men jeg har her valgt at fokusere på optimering af PHP kode.


Om de udføte tests

I de eksempler jeg giver i denne artikel, er hver kode testet i 4 udvendige iterationer og 1.000.000 invendige iterationer, altså er hver kode eksekveret 4.000.000 gange.
Idet den interne cache i PHP vil have størst indflydelse på den første udvendige iteration, har jeg kun brugt resultaterne fra de sidste 3 udvendige iterationer.

For at opnå et estimat for hvor lang tid min kode er om at eksekveres, anvender jeg microtime() [1].

Den grafiske representation af mine resultater er gennemsnit af de sidste 3 udvendige iterationer i fold i forhold til den langsommeste. Alle resultater er +/- standardafvigelsen. Det vil altså sige, at hver bar er gennemsnits fold i forhold til den langsommeste metode.

Altså ser min kode ud som herunder:
Fold kodeboks ind/udKode 


Al kode blev afviklet gennem CLI på min gode gamle bærbare computer. Alle tests blev afviklet individuelt.



Simpel matematik

PHP er typesvagt, og du kan derfor tillade dig ting i PHP som vil få de fleste andre sprog (deres compilere) til at få en slem hoste...eller det som er værre...

I PHP kan man bruge matematiske operatorer på forskellige datatype, som f.eks. strenge og heltal, eksempel:

Fold kodeboks ind/udKode 


Koden herover vil udskrive noget i retning af:


10
Integer


Denne operation er i sig selv ganske fantastisk, vi beder (måske pænt) om at få adderet en streng med et heltal og PHP brokker sig ikke :) Underligt... Det er jo to forskellige datatyper. Hvad der er endnu mere fantastisk er, at PHP rent faktisk forstår hvad vi prøver at sige, og den giver oven i købet resultatet som den korrekte datatype - et heltal.

Man kan blive ved med at lave disse "fantastiske" ting, double + streng = double, osv...

Det er nu vist, at man kan tage værdier som streng og anvende dem til matematik - men betyder det at man skal gøre brug af det?

Svaret er, at det kommer an på, hvad man skal bruge det til. Hvis du bare skal lave en enkelt udregning, så er svaret ja (i min verden i hvert fald). Det kan ikke betale sig at typecaste en variable til brug en enkelt gang. Skal du derimod bruge variablen mange gange senere hen, er det nok en god ide at caste den til en mere matematisk korrekt variabel.
Det er værd at nævne at værdier i $_GET og $_POST altid vil være strenge.

Og nu til det denne artikel handler om - hvor stor er foreskellen på at bruge korrekte typer?

figur 1 herunder bygger på følgende kode:

Fold kodeboks ind/udKode 

figur 1


Som man ser på figur 1, er det ca. 1,7 fold langsommere at addere hvis man lader det være op til PHP at bestemme datatyperne. Hvis man kun skal lave enkelte additioner, har dette ingen praktisk betydning, men hvis man skal lave statistik eller noget andet som kræver mange udregninger, kan det godt have en praktisk betydning.

figur 2 herunder bygger på følgende kode, og viser samme tendens for division som for addition:

Fold kodeboks ind/udKode 


figur 2


At man ser den samme fold for addition og division er ikke overraskende, selvom division er mere kompliceret. Det skyldes at vi ser på den operationsuafhængige typebestemmelse af $number.





<< < 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