Mailinglisten-Archive |
Am 2013-08-12 12:16, schrieb Thomas Koudela: > Hallo Michael. > > 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 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). > 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. 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. > Ü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. Yannik
php::bar PHP Wiki - Listenarchive