Gå til innhold

Guide: PHP- & MySQL-innføring: Kapittel 4


Anbefalte innlegg

Videoannonse
Annonse

Ser at dere konsekvent legger inn count() i selve løkke-definisjonen. Det er dårlig praksis. Count() vil da kjøres for hver iterasjon; noe som gir dårlig ytelse.

 

Er ikke min erfaring. Min erfaring er at standarden med array.length, list.size() og slike i en for-løkke overhodet ikke påvirker ytelsen, som får meg til å tro at dette mellomlagres under panseret. Gikk på en smell på det en gang jeg iterte over en liste og skulle slette elementer. Ble noe slik:

for(int i=0;i&--#60;list.length;i++) {

if(#ensjekk)

list.remove(i);

}

Ser straightforward ut? Det er det ikke. Etter hvert som elementer fjernes fra lista, så blir den kortere. For-løkka bestemmer seg for hvor mange ganger den skal itere første gang, som gjør at den plutselig når indekser som ikke finnes lengre.

Endret av Mads-b
Lenke til kommentar

I andre språk caches nok slike enkle ting, men ikke i PHP. Omtrent alle ytelsesblogger på nettet advarer mot praksisen. Hva om det var noe mer komplekst enn en enkel count-funksjon?

 

Feilen du viser over er classic! Har gjort den selv en gang også! :-) For-setninger bør i grunn unngås med mindre man faktisk trenger iteratoren til noe spesifikt.

Lenke til kommentar

Det interessante med PHP er at array ikke er en klassisk array slik man finner i f.eks C++ eller Java for den del.

 

PHP sin array er en "ordered hashmap". Det er litt vesentlig for å kunne forstå hvordan man kan utnytte PHP sin array best mulig.

 

Ta f.eks sort() - det er totalt meningsløst. Stort sett vil man hente data fra databasen med sql, og da er det bare til å slenge på en "order by", og vips er resultatet sortert. Samme triks gjelder forsåvidt for Java også, men at man da benytter LinkedHashMap.

 

Men her begynner man å se hvor ille PHP er når man viser til ørten sorteringsfunksjoner - som forøvrig er hardkodet inn i PHP kjernen og dermed utgjør hovedgrunnen til at PHP ikke kan utvikles videre. Det er sinnsykt lite fleksibelt. I Java så lager man sin helt egen sortering ved å implementere et interface og har enorm fleksibilitet, for det er ikke så vanskelig å sortere fremover og bakover om man fulgte med på skolen.

 

Java er så kraftig at vi kan gjøre vår variant av "count" feilen nevnt av andre i tråden - uten at det betyr særlig. Vi må gjøre en insats for å knele Java.

Lenke til kommentar
Ser at dere konsekvent legger inn count() i selve løkke-definisjonen. Det er dårlig praksis. Count() vil da kjøres for hver iterasjon; noe som gir dårlig ytelse.
Er ikke min erfaring. Min erfaring er at standarden med array.length, list.size() og slike i en for-løkke overhodet ikke påvirker ytelsen, som får meg til å tro at dette mellomlagres under panseret. Gikk på en smell på det en gang jeg iterte over en liste og skulle slette elementer. Ble noe slik:for(int i=0;i&--#60;list.length;i++) {if(#ensjekk) list.remove(i);}Ser straightforward ut? Det er det ikke. Etter hvert som elementer fjernes fra lista, så blir den kortere. For-løkka bestemmer seg for hvor mange ganger den skal itere første gang, som gjør at den plutselig når indekser som ikke finnes lengre.

 

Dersom PHP her cacher Count() så er implementasjonen direkte FEIL. Det er aldri riktig å cache en verdi fra et funksjonskall med mindre dette funksjonskallet er konstant, så det tviler jeg ekstremt mye på at den gjør.

Det som derimot skjer er at du vil hoppe over en indeks dersom du sletter et element. Aldri slett elementer fra en liste som blir iterert over! Noensinne! Legg det i et eget array istedet, enten ved å flytte elementer som skal taes vare på, eller lag en liste over elementer som skal slettes.

 

I bedre programmeringsmiljøer vil du programmet tryne dersom du prøver å slette elementer fra en liste som blir iterert over.

  • Liker 1
Lenke til kommentar
Ser at dere konsekvent legger inn count() i selve løkke-definisjonen. Det er dårlig praksis. Count() vil da kjøres for hver iterasjon; noe som gir dårlig ytelse.
Er ikke min erfaring. Min erfaring er at standarden med array.length, list.size() og slike i en for-løkke overhodet ikke påvirker ytelsen, som får meg til å tro at dette mellomlagres under panseret. Gikk på en smell på det en gang jeg iterte over en liste og skulle slette elementer. Ble noe slik:for(int i=0;i&--#60;list.length;i++) {if(#ensjekk) list.remove(i);}Ser straightforward ut? Det er det ikke. Etter hvert som elementer fjernes fra lista, så blir den kortere. For-løkka bestemmer seg for hvor mange ganger den skal itere første gang, som gjør at den plutselig når indekser som ikke finnes lengre.

 

Dersom PHP her cacher Count() så er implementasjonen direkte FEIL. Det er aldri riktig å cache en verdi fra et funksjonskall med mindre dette funksjonskallet er konstant, så det tviler jeg ekstremt mye på at den gjør.

Det som derimot skjer er at du vil hoppe over en indeks dersom du sletter et element. Aldri slett elementer fra en liste som blir iterert over! Noensinne! Legg det i et eget array istedet, enten ved å flytte elementer som skal taes vare på, eller lag en liste over elementer som skal slettes.

 

I bedre programmeringsmiljøer vil du programmet tryne dersom du prøver å slette elementer fra en liste som blir iterert over.

 

Koden var et eksempel på en case der size() faktisk bare ble kjørt en gang, og som dermed trynet, ikke et eksempel på god kodepraksis. Hadde du lest litt nærmere ville du også ha sett at dette er en _liste_ og ikke et array, hintet om i variabelnavn. Lenkede lister "hopper" ikke over indekser; De bare lenker seg sammen igjen om man sletter elementer, som gjør det godt mulig å ende opp på en listeindeks som ikke finnes mer.

 

Men tilbake til tema: Mange språk cacher lengden på strenger, lister og andre komposittobjekter ved å oppbevare denne i objektet, og oppdatere denne når objektet endres. Kall til string.length eller en eller annen liste.size() i java er gode eksempler på dette; De returnerer konstanter.

 

Men akk, om programmeringsspråk var en barnehage, så er PHP den tilbakestående, spinkle kvisten som sitter i et hjørne i sandkassa og spiser sand. Dere har dessverre rett her; Det er et av de få språk som ikke oppbevarer denne konstanten i objektene, samt at det er ingen kompilator som optimaliserer før runtime.

Lenke til kommentar

Java og C# kaster exception dersom du prøver å endre en liste mens du itererer over den (java har derimot iterator.remove() for å slette elementet der man er i iterasjonen). string.length er konstant fordi strings er immutable, noe list ikke er. Lengden på en liste er ikke konstant. Lengden på en string derimot er det, så en skal ikke se bortifra at string.length er final i Java og readonly i .NET.

PHP er derimot uansett helt på jordet, og det at list faktisk ikke er et dynamisk array, eller engang en linked list, men et hashmap, er enda en av de fantastisk mange fallgruvene som PHP har prestert å presse inn.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...