phpbar.de logo

Mailinglisten-Archive

[php] Zeitproblem beim Methodenaufruf

[php] Zeitproblem beim Methodenaufruf

Michael Fuhrmann technik at piaunddirk.de
Mo Aug 12 14:13:10 CEST 2013


Hi Yannik,

danke für den Input bezüglich des Unsets. Ich hatte echt schon Sorge, das
Ganze bis ins Unschöne steigern zu müssen.

Zu meinen Objekten: Es ist nicht die Größe, die bei den Objekten Probleme
macht, sondern der Zugriff innerhalb einer komplexen Baumsturktur. Um
Datenbankzugriffe zu minimieren, muss ich diverse Strategien verfolgen,
darunter auch Cachen von Resultaten in statischen Klassen. Und wie es jetzt
aussieht, war eine davon etwas dumm gebaut. Sie hat sich mit der Menge an
Objekten, die zu verarbeiten waren, unschön hochgeschaukelt. Manche Sachen
fallen eben erst ab Durchlauf 1000 bis 10000 auf.

Hab viel gelernt durch diesen "Fehler" (korrekt lief es ja. Halt nur nicht
in O(1)).

Noch etwas Klugscheißen am Ende: PHP ist ein Interpreter und kein Complier.
;)


Beste Grüße
Michael Fuhrmann


-----Ursprüngliche Nachricht-----
Von: php [mailto:php-bounces at lists.phpbar.de] Im Auftrag von Yannik Hampe
Gesendet: Montag, 12. August 2013 13:21
An: deutschsprachige PHP-Mailingliste
Betreff: Re: [php] Zeitproblem beim Methodenaufruf

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

--
** Allgemeine deutschsprachige PHP-Liste: php at lists.phpbar.de **
Informationen: http://www.phpbar.de
http://lists.phpbar.de/cgi-bin/mailman/listinfo/php



Mehr Informationen über die Mailingliste php

php::bar PHP Wiki   -   Listenarchive