phpbar.de logo

Mailinglisten-Archive

[php] Zeitproblem beim Methodenaufruf

[php] Zeitproblem beim Methodenaufruf

Thomas Koudela thomas at koudela.net
Mo Aug 12 21:27:27 CEST 2013


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



Mehr Informationen über die Mailingliste php

php::bar PHP Wiki   -   Listenarchive