Mailinglisten-Archive |
Hallo Yannik, hallo Thomas, das unset hat auf jedenfall einen Mehrwert. Es löst explizit __destruct() aus. Darin habe ich Schreibbefehle untergebracht. Somit kann ich am Objekt rumändern und ganz simpel am Ende die Änderungen am Stück wegschreiben lassen. Damit hat man praktisch auch die Möglichkeit eine Art Transaktionsabbruch einzubauen. Das unset wirkt dann als verkapptes commit. Beste Grüße Michael Fuhrmann -----Ursprüngliche Nachricht----- Von: php [mailto:php-bounces at lists.phpbar.de] Im Auftrag von Thomas Koudela Gesendet: Montag, 12. August 2013 21:27 An: deutschsprachige PHP-Mailingliste Betreff: Re: [php] Zeitproblem beim Methodenaufruf 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 -- ** Allgemeine deutschsprachige PHP-Liste: php at lists.phpbar.de ** Informationen: http://www.phpbar.de http://lists.phpbar.de/cgi-bin/mailman/listinfo/php
php::bar PHP Wiki - Listenarchive