phpbar.de logo

Mailinglisten-Archive

[php] Zeitproblem beim Methodenaufruf

[php] Zeitproblem beim Methodenaufruf

Yannik Hampe yannik at cipher-code.de
Mo Aug 12 13:20:50 CEST 2013


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



Mehr Informationen über die Mailingliste php

php::bar PHP Wiki   -   Listenarchive