php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2007

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 28.04.2007, 21:13  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard Lambda-Funktion und array_map/_filter gegen foreach

So, das habe ich jetzt. Die Gründe dazu sind erstmal wurscht, aber ich hab mal wieder eine lustige Performance-Frage
PHP-Code:
        $tempFunc create_function('$methodName'
                                    
'return (substr ($methodName, -6) === "Action");');
        
$actions  array_filter (get_class_methods($this),$tempFunc);
        
$tempFunc create_function('$methodName',
                                    
'return substr ($methodName, 0, -6);');
        
$actions  array_map ($tempFunc$actions);
        
        foreach (
$actions as $action) {
            
// Do something useful
        

Vorher hatte ich das so, bevor ich es auf obige Variante (zu Gunsten der wie ich finde Übersichtlichkeit) umgeschrieben habe:
PHP-Code:
$actions get_class_methods ($this);
foreach (
$actions as $action) {
    if (
substr ($methodName, -6) === "Action") {
        continue;
    }
    
$action substr ($methodName0, -6););
    
// Do something useful

Naja, wer sich da nicht reinlesen will: Diese beiden Code-Schnippsel lesen die Methoden-Namen der eigenen Klasse, sortieren alle raus, die nicht auf Action enden und schneiden vom Rest das Action am Ende ab.

Meine Fragen zielen nun auf zwei Sachen:
1. Was kann man als perfomanter einstufen? Die erste Variante sollte mit array_map und array_filter kleinere Vorteile in Bezug auf Iteration liefern, aber leider wird dann ja insgesamt sogar 3 mal (einmal immer noch mit foreach) über das Array iteriert. Andererseits ist die foreach-Iteration dadurch kleiner und von "Unrat" befreit.

2. Inwiefern sind die anonymen Funktionen einzuschätzen? Ich hab die da oben nunmal so gebraucht, weil die beiden Array-Funktionen nunmal einstellige Callbacks fordern. Is das aber so sinnvoll? ^^ Denkbar wäre ja auch ne Konstruktion mit array_walk, der beide Schritte gleichzeitig durchzieht. ^^
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 28.04.2007, 21:19  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo KingCrunch,

ohne das zu testen kann ich dir keine wirklich ehrliche Antwort geben. Ich würde das an deiner Stelle mal benchmarken und anschließend auswerten.

Wenn es um Ästhetik geht, ziehe ich Version 2 vor, da diese ergeblich schlanker ist. Man könnte sich fast dazu hinleiten lassen und auf Grund der Kompaktheit auch mehr Schnelligkeit zu attestieren..
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Alt 28.04.2007, 21:43  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard

OK, ma auf die schnelle was auf Basis dieser PHP-Benchmarks was zusammen gebastelt.

Benchmark-Umgebung:
PHP-Code:
<?PHP
//
// Wir starten die Zeitmessung - das wird durch Instanzieren
// einer Timer-Klasse getan
//
$start microtime (true);
//
// require ('testclss1.php');
require ('testclass2.php');
$obj = new test();



//

// Schleife für die Iterationen

//

for ($meine_zaehlvariable=0$meine_zaehlvariable<10000$meine_zaehlvariable++) {
    
//
    // Damit eventueller Output nicht angezeigt wird, schreiben wir ihn
    // in den Ausgabe-Puffer
    //
    
ob_start ();

    
//
    // Hier steht jeweils der zu prüfende Code
    //
    
$obj->test ();
    
//
    // Wir deaktivieren das OB und löschen den Puffer (bei jedem Durchlauf)
    //
    
ob_end_clean ();
}
//
// Wir bestimmen die Laufzeit
//

var_dump (microtime (true) - $start);
?>
Test-Vorraussetzung:
PHP-Code:
<?php
abstract class testPre {
    public function 
aAction () {}
    public function 
bAction () {}
    public function 
cAction () {}
    public function 
dAction () {}
    public function 
eAction () {}
    public function 
fAction () {}
    public function 
gAction () {}
    public function 
hAction () {}
    public function 
iAction () {}
    public function 
jAction () {}
    public function 
aElse (){}
    public function 
bElse (){}
    public function 
cElse (){}
    public function 
dElse (){}
    public function 
eElse (){}
    public function 
fElse (){}
    public function 
gElse (){}
    public function 
hElse (){}
    public function 
iElse (){}
    public function 
jElse (){}
}
?>
Test 1:
PHP-Code:
<?php
require ('testabstract.php');
class 
test extends testPre {
    public function 
test ()
    {
        
$tempFunc create_function('$methodName',
        
'return (substr ($methodName, -6) === "Action");');
        
$actions  array_filter (get_class_methods($this),$tempFunc);
        
$tempFunc create_function('$methodName',
        
'return substr ($methodName, 0, -6);');
        
$actions  array_map ($tempFunc$actions);

        foreach (
$actions as $action) {
            
// Do something useful
        
}
    }
}
?>
Test 2:
PHP-Code:
<?php
require ('testabstract.php');
class 
test extends testPre {
    public function 
test ()
    {
        
$actions get_class_methods ($this);
        foreach (
$actions as $action) {
            if (
substr ($methodName, -6) === "Action") {
                continue;
            }
            
$action substr ($methodName0, -6);
            
// Do something useful
        
}
    }
}
?>
Das die zu testenden Methoden leer sind, sollte kein Abbruch darstellen, weil beide Klassen ja den selben Vor-/Nachteil haben. Insofern die (von mir ) gerundeten Ergebnisse:
- Test 1: Etwa 2 bis 2,2 Sekunden
- Test 2: Etwa 1,2 bis 1,3 Sekunden
Die schlankere Variante ist also wirklich schneller. Was ich allerdings noch kritisch betrachte ist, dass die foreach ansonsten leer ist und ich nicht weiß, inwiefern das das Resultat verfälscht ... Und die array_walk-Variante fehlt, aber dazu hab ich auch noch keine mögliche Implementation Vielleicht, ma schaun, aber glaub kaum, dass es das Ergebniss fundamental beeinflusst
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline  
Alt 28.04.2007, 22:44  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Damit wäre die Vermutung aber bewiesen. Ich benchmarke regelmäßig meinen Code und habe dazu einen benchmarktTimer, den ich in den entsprechenden Code-Teilen singleton einbinde. In der index.php lasse ich mir dann am Ende einen Report ausgeben, der ungefähr so aussieht:

http://christian.zierpflanzenberatun...arkreport=true

Sollte er dich interessieren, kannst du dir ja mal die Klasse "benchmarkTimer" im Ordner "/apps/core/benchmark" ansehen unter http://christian.zierpflanzenberatun...eite=Downloads.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Alt 28.04.2007, 23:18  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard

Die Ausgabe sieht recht interessant aus. Frag mich bloss, ob die ganzen Informationen (Objekt-ID?) wirklich sinnvoll sind. Wie du vielleicht gesehen hast, verwendet die Seite, von der ich mich hab inspirieren lassen, auch ne eigene Klasse. Die konnte ich aber leider net finden, deshalb das schnelle Workaround

Wollte da mir jetzt auch was zusammen basteln. Möglicherweise lasse ich mich da mal ein bisschen inspirieren Noch steige ich nicht ganz durch, aber sieht vielversprechend aus. Vorallen das mit der kritischen Zeit und die "Stapelung" find ich interessant. Is aber vielleicht nen bisschen viel Ausgabe hardcoded
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline  
Alt 29.04.2007, 10:28  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo KingCrunch,

Zitat:
Die Ausgabe sieht recht interessant aus. Frag mich bloss, ob die ganzen Informationen (Objekt-ID?) wirklich sinnvoll sind.
Das sind sie für mich schon. Hintergrund ist der, dass alle Objekte der Präsentations-Schicht eine interne Objekt-ID haben, mit der man sie im Baum adressieren kann. Da der benchmarkTimer global eingesetzt wird und man ihn mit beliebigen Schlüsseln starten und stoppen kann, brauche ich eine Unterscheidung, welches Objekt gerade z.B. onAfterAppend() ausgeführt hat. Grundsätzlich kannst du aber eigene Schlüssel-Bezeichnungen vergeben um einen Timer zu starten und zu stoppen. Da ich mehrere Timer unterstütze muss der einzelne natürlich unique sein.


Zitat:
Vorallen das mit der kritischen Zeit und die "Stapelung" find ich interessant. Is aber vielleicht nen bisschen viel Ausgabe hardcoded :Wink
Die "Stapelung" ist quasi die Hirarchie, in der die einzelnen Timer gestartet werden. Man kann somit einen globalen Prozess in seiner totalen Granularität benchmarken, wenn man das möchte. Daraus ergibt sich dann ein Baum und man sieht genau, wo welche Zeit verbraucht wurde. Die Struktur gibt auch ungefähr die Baum-Struktur der Präsentations-Schicht wieder...
Die Ausgabe ist einfach nur blödes HTML, nicht unbedingt schön, aber diese Ausgabe wird ja nur dann auch dem User gezeigt, wenn man das auch möchte. Ich brauch mir also keine Gedanken machen, ob der den W3C-Check besteht - was er wahrscheinlich nicht tun wird .
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
JS: Einführung - Javascript im Schichtenmodell nikosch Tutorials 4 11.04.2009 17:06
Rekursive Funktion bricht ab... duras666 PHP Tipps 2008 9 28.04.2008 11:36
gpc_quotes funktion: verbesserungsvorschläge? Promaetheus PHP Tipps 2007 10 12.08.2007 19:29
Komplexe Funktion: +Übersichtlichkeit, -Performance Jacks Rache PHP Tipps 2006 3 07.06.2006 14:22
durch foreach auch normalen String durchlaufen lassen PHP Tipps 2006 7 14.01.2006 13:20
PHP-GTK Tutorial Beitragsarchiv 9 02.11.2005 21:07
$_FILES mit foreach() PHP Tipps 2005-2 5 20.10.2005 10:27
Rückgabewert einer rekrusiven Funktion PHP-Fortgeschrittene 7 06.10.2005 18:44
(schnellere) Funktion zum Zusammenfassen von CSS PHP-Fortgeschrittene 21 08.08.2005 16:47
In einer Funktion auf eine Funktion der Klasse zugreifen phpbeginner PHP Tipps 2005-2 2 28.07.2005 00:30
Funktion in einer Funktion aufrufen? PHP Tipps 2005-2 11 14.06.2005 15:14
[Erledigt] Array-Übergabe in Funktion PHP Tipps 2005 1 08.05.2005 21:05
[Erledigt] Wie kann ich beliebig viele Werte an eine Funktion übergeben PHP Tipps 2005 11 25.01.2005 10:44
[Erledigt] sql syntax error in funktion, kann aber nix finden :( PHP Tipps 2004 10 20.07.2004 19:19
[Erledigt] Referenz auf Funktion übergeben PHP-Fortgeschrittene 7 20.07.2004 09:51

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php array_map performance, php array_map foreach, array_map lambda, array_map mit objekten, php array_map substr, php array_map oder foreach, array_map substr, core foreach einmal, array_map vs foreach, php benchmark array_map, for_each lambda, array_walk vs foreach performance, performance php array_map for, array_map performance lambda, php array_map foreach performance, php array_map vs foreach, array_filter foreach performance, php performance array_filter, array_map oder foreach, php \array_filter\ foreach performance

Alle Zeitangaben in WEZ +2. Es ist jetzt 16:27 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.