17
Tags:
php
Skrevet af
Bruger #4683
@ 08.05.2008
LøkkerLø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:
$array = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
$string = "12345678901234567890";
for ($j = 0; $j < 4; $j++) {
$s = microtime(1);
for ($i = 1;$i<1000001;$i++) {
for ($k=0;$k<count($array);$k++) {
}
}
$e = microtime(1);
print "\\ntime: ".($e-$s);
}
for ($j = 0; $j < 4; $j++) {
$s = microtime(1);
for ($i = 1;$i<1000001;$i++) {
$cn = count($array);
for ($k=0;$k<$cn;$k++) {
}
}
$e = microtime(1);
print "\\ntime: ".($e-$s);
for ($j = 0; $j < 4; $j++) {
$s = microtime(1);
for ($i = 1;$i<1000001;$i++) {
for ($k=0;$k<strlen($string);$k++) {
}
}
$e = microtime(1);
print "\\ntime: ".($e-$s);
}
for ($j = 0; $j < 4; $j++) {
$s = microtime(1);
for ($i = 1;$i<1000001;$i++) {
$strlen = strlen($string);
for ($k=0;$k<$strlen;$k++) {
}
}
$e = microtime(1);
print "\\ntime: ".($e-$s);
}
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 3De 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.
ArraysArrays 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:
<?php
error_reporting(1);
for ($j = 0; $j < 4; $j++) {
$s = microtime(1);
$array = array("key" => "value");
for ($i = 0;$i<1000000;$i++) {
$array[key] = $i;
}
$e = microtime(1);
print "\\ntime: ".($e - $s);
}
for ($j = 0; $j < 4; $j++) {
$s = microtime(1);
$array = array("key" => "value");
for ($i = 0;$i<1000000;$i++) {
$array["key"] = $i;
}
$e = microtime(1);
print "\\ntime: ".($e - $s);
}
?>
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 4Afsluttende 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
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)
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.
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.).
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
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.
God artikel!
God - Jeg blev klogere
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
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.
"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?
"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
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...
God artikel.
Selvom, jeg har læst nogle mere detaljerede på engelsk, rundt om kring. (Søg evt. på "optimize php scripts" på Google)
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
Var faktisk nogle små rare ting som er gode at vide
Du skal være
logget ind for at skrive en kommentar.