Mailinglisten-Archive |
Hallo Yannik. >> In Deinem Programm passiert folgendes: Bei jedem Schleifendurchlauf >> wird eine neue Instanz Deiner Klasse erzeugt. Zwar weiß der >> Garbage-Collector, dass Du $inst überschreibst, und damit dass er die >> alte Instanz löschen kann, jedoch wird er nicht automatisch bei jeder >> Variablenzuweisung ausgelöst. Deshalb benötigst Du das unset()! > > Der Garbage collector wird von PHP nach eigenem Ermessen ausgeführt. > unset() hat in diesem Fall nicht mehr Einfluss als die Referenz zu > überschreiben. > > Also: > > Folgende Zeile: > > $a = new StdClass(); > > erzeugt ein neues Objekt vom Typ StdClass und speichert eine > Referenz in $a. PHP führt eine Referenzzählung durch und das > erzeugte Objekt hat jetzt eine Referenzzahl von 1. Sobald die > Referenz auf dieses Objekt aufgehoben wird (zum Beispiel durch `$a = > null;`, `unset($a);` oder auch `$a = "foobar";` geht der > Refernzzähler auf 0 zurück und sobald der Garbage collector losläuft > wird er das Objekt aus dem Speicher entfernen. Es ist dabei völlig > egal welche der Methoden du wählst. > Der einzige Vorteil von unset wäre, dass die Referenz selbst auch > nicht mehr existiert. Also PHP weiß danach nichtmehr, dass überhaupt > eine Variable mit dem Namen $a jemals existiert hat. Wenn du > allerdings direkt nach einem unset($a) wieder einen neuen Wert $a > zuweist, dann bringt dies nichts. Ich glaube dass diese Theorie nicht 1:1 umgesetzt ist, da in den PHP-Manual-Kommentaren (http://www.php.net/manual/de/function.unset.php#105980) von erheblichen Performance- und Speicherverbrauchsunterschieden zwischen $a = null und unset($a) berichtet wird. Daher bleibe ich persönlich bei meiner Präferenz für unset(). >> (Ich finde dies ein schönes Beispiel was guten Code von lediglich >> funktionierendem unterscheidet. Leider bekommen Kunden/Arbeitsgeber >> davon in der Regel nichts mit. Aber zurück zum Problem.) > > Ich finde es gut, wenn Leute darüber nachdenken, wie man Code besser > machen kann. Allerdings solltest du meiner Meinung nach nicht die > Aufgabe des Compilers, der Laufzeitumgebung, etc. erledigen. Dies > macht den code nicht schneller, sondern nur unlesbarer (aber keine > Sorge: Der Wert von lesbaren Code kommt bei Kunden/Arbeitgebern auch > häufig nicht an). Es geht doch gar nicht darum die Aufgaben des Compilers zu übernehmen, sondern Artefakte bei der Programmierung zu vermeiden. Ein expliziter Code erhöht dabei eher die Lesbarkeit - zumindest empfinde ich das so. Aber zurück zu Michels Problem... Ich habe dazu interessantes gefunden... www.php.net/manual/de/function.unset.php#105980 möglicherweise schon: »unset($class_object) does not release resources allocated by the object. If used in loops, which create and destroy objects, that might easily lead to a resource problem. Explicitly call the destructor to circumvent the problem.« statt: unset($inst); also: $inst->__destruct(); unset($inst); >> Da weder der Garbage-Collector aktiviert wird, noch der Speicher >> direkt freigegeben wird, schreibst Du dir erst den 1st-Level Cache, >> dann den 2nd-Level Cache, dann den 3nd-Level Cache (falls vorhanden), >> dann den Arbeitsspeicher und zum Schluss die SWAP-Partition der >> Festplatte voll. Diese Speicher sind nicht nur sukzessive langsamer, >> sondern bei der Auslagerung geht zusätzlich Zeit verloren. Die >> Ergebnisse deiner Zeitmessung sind daher nicht verwunderlich. > > Wenn du mit dem Anlegen von 3000 Objekten bereits deinen RAM voll > hast, dann würde ich mir ernsthaft Gedanken darüber machen was für > Monster-Objekte dies sind oder wie klein dein RAM ist. Sagen wir mal > jedes Objekt hat 1KB, was schon eine solide Größe sein sollte, dann > sind 3K Objekte gerade mal 3 MB. Das würde noch voll in den > CPU-Cache aktueller CPUs passen. Bei der Standard-Webseite hast Du recht. Mit PHP-Objekten, die Grafiken handeln, kann ich dagegen den Arbeitsspeicher jedes Standard-PCs vollmüllen, wenn PHP nicht aufgrund der Einstellungen der PHP-INI vorher aussteigt. > Mal abgesehen davon ist dies nicht die Arbeitsweise des CPU-Cache. > Wenn du auf Daten lange Zeit nicht zugegriffen hast, dann werden > alte Daten auch aus dem Cache wieder rausgeworfen um für neue Daten > Platz zu machen. Und auf diese Daten hast du dann ja lange nicht > zugegriffen. Bitte habe Verständnis dafür, dass ich in meinen Mails nicht jedes Detail ausführe, da mir dazu die Muse fehlt. >> Überhaupt würde ich an Deiner Stelle prüfen, ob ich nicht mit einer >> Instanz auskomme, die ich eventuell mit einer extra Methode nur neu >> initialisiere, denn das Löschen und Erzeugen einer ganzen Instanz >> kostet in der Regel mehr Zeit als die Neubelegung einiger >> Instanz-Variablen. > > Dies ist zwar korrekt, allerdings sollten die Auswirkungen bei > kleinen Objektzahlen gering sein. Die Lesbarkeit vom Quelltext ist > meiner Meinung nach am Ende im Zweifelsfall wichtiger. Zustimmung. Mit Betonung auf »im Zweifelsfall«. ;) > Yannik Gruß, Thomas -- Thomas Koudela Programmierdienstleistungen von A bis Web Mozartstraße 6 D-45529 Hattingen Tel: +49 (0)2324-392320 Email: service at koudela.net Internet: http://www.koudela.net
php::bar PHP Wiki - Listenarchive