phpbar.de logo

Mailinglisten-Archive

[php] Zeitproblem beim Methodenaufruf

[php] Zeitproblem beim Methodenaufruf

Michael Fuhrmann technik at piaunddirk.de
Mi Aug 14 18:26:14 CEST 2013


Hallo,

nochmal etwas zum Thema "langsam". Bei großen (wachsenden) Arrays ist
array_key_exists die schlechtere Wahl. Wieso läuft diese Funktion in
irgendwas größer als O(1) und nicht wie isset in O(1)? (PHP 5.3.2) Ich
meine, isset reagiert ja auf NULL allergisch. Ist das bei späteren PHP
Versionen anders?


Beste Grüße/Cordialement:
Michael Fuhrmann


**************************************
Folge uns auf Facebook, Twitter oder google plus:
 
Reisen macht Spaß…mit Pia und Dirk eKfm.
Dirk Bruhn
Schieferstrasse 14
65388 Schlangenbad-Bärstadt

Tel: 0049 6129 9081
Fax: 0049 6129 9041

E-Mail: PiaundDirk at PiaundDirk.de

Webseite: http://www.PiaundDirk.de

Handelsregister Wiesbaden HRA 6186
UST ID Nr: DE 189 62 73 42
Steuer Nr: 04 8083 05 15 

-----Ursprüngliche Nachricht-----
Von: php [mailto:php-bounces at lists.phpbar.de] Im Auftrag von Michael
Fuhrmann
Gesendet: Dienstag, 13. August 2013 10:30
An: 'deutschsprachige PHP-Mailingliste'
Betreff: Re: [php] Zeitproblem beim Methodenaufruf

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

--
** 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