| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |
|

24-06-2009, 21:17
|
|
RamonaS
Registrierter Benutzer
|
|
Registriert seit: Mar 2009
Beiträge: 177
|
|
Diesen Code optimieren?
Kann man den code hier kürzer schreiben, um den Counter immer 6-stellig zu haben?
PHP-Code:
$counter=str_pad($counter,6,"0",STR_PAD_LEFT);
Und hier auch nochmal: Gibts vielleicht eine fertige funktion
um die letzten array-Einträge schneller zu prüfen?
PHP-Code:
if(count($arr)>2) # Nur die letzten 3 Dateizeilen prüfen
{for($i=2;$i>=0;--$i)
{$z=explode("|",trim($arr[count($arr)-$i-1]));
...
}
}
|

24-06-2009, 21:21
|
unset
 Moderator
|
|
Registriert seit: Jan 2007
Ort: Düsseldorf
Beiträge: 3.778
|
|
Das erste Beispiel lässt sich wohl nicht mehr weiter kürzen.
Beim zweiten bin ich mir da nicht so sicher. Allerdings: for-Schleifen für Arrays sind wesentlich unperformanter als foreach-Schleifen.
|

24-06-2009, 21:49
|
|
deedee
Registrierter Benutzer
|
|
Registriert seit: Jun 2009
Beiträge: 80
|
|
Ich würde es so machen:
PHP-Code:
if(($nCount=count($arr))>2) # Nur die letzten 3 Dateizeilen prüfen
{for($i=$nCount-3;$i<$nCount;++$i)
{$z=explode("|",trim($arr[$i]));
...
}
}
oder so, falls es egal ist, dass das Array dann verändert wird:
PHP-Code:
if(count($arr)>2)
{for($i=0;$i<3;++$i)
{$z=explode("|",trim(array_pop($arr));
...
}
}
Geändert von deedee (24-06-2009 um 21:57 Uhr)
|

24-06-2009, 21:50
|
|
h3ll
Registrierter Benutzer
|
|
Registriert seit: Mar 2008
Beiträge: 2.328
|
|
Zitat:
Zitat von RamonaS
Kann man den code hier kürzer schreiben, um den Counter immer 6-stellig zu haben?
PHP-Code:
$counter=str_pad($counter,6,"0",STR_PAD_LEFT);
|
PHP-Code:
$counter = sprintf("%06d", $counter);
|

24-06-2009, 23:42
|
 |
fireweasel
Registrierter Benutzer
|
|
Registriert seit: Sep 2008
Ort: At home
Beiträge: 680
|
|
Zitat:
Zitat von RamonaS
... Und hier auch nochmal: Gibts vielleicht eine fertige funktion
um die letzten array-Einträge schneller zu prüfen?
|
Ja, sie heißt prev().
Sie ist meist nur in Zusammenhang mit end() sinnvoll nutzbar. Und für deinen Fall benötigen wir noch key().
PHP-Code:
for (end($arr), $i = 3; $i && (NULL !== $key = key($arr)); prev($arr), --$i) {
$z = explode('|', trim($arr[$key]));
// ...
}
Man kann das ganze auch dekorativer gestalten, aber for() bietet die Möglichkeit, alles in den Schleifenkopf reinzupacken. Sonst hätte der Trick auch nicht in 3 Zeilen gepasst.
PHP-Code:
end($arr); // Array-Zeiger aufs Ende setzen
$i = 3; // Anzahl der letzten Elemente festlegen
while (NULL !== $key = key($arr)) {
if (empty($i)) {
break;
}
$z = explode('|', trim($arr[$key]));
// ...
prev($arr); // Array-Zeiger eins runter
--$i; // noch zu bearbeitende Elemente
}
... und weil mir gerade so war: Es gibt auch eine foreach()-Lösung:
PHP-Code:
foreach (array_slice($arr, -3) as & $line) {
$z = explode('|', trim($line));
}
*nachschieb*
... jaaaa, das & ist vollkommen überflüssig, in meinem getestetem Original-Quältext gabs das auch nicht (hab extra nochmal nachgekuckt). Ich habe keine Ahnung, wieso ich das nach'm Kopieren noch hinzugefügt hatte. :emm:
__________________
PHP-Code:
class Brick implements Throwable {
// ...
}
Geändert von fireweasel (03-07-2009 um 12:27 Uhr)
|

25-06-2009, 14:05
|
|
RamonaS
Registrierter Benutzer
|
|
Registriert seit: Mar 2009
Beiträge: 177
|
|
Hallo...
Danke für die schnelle Hilfe!
Ich habe mich für: $counter = sprintf("%06d", $counter);
von h3ll
und die foreach lösung von fireweasel entschieden
 
|

03-07-2009, 01:14
|
|
RamonaS
Registrierter Benutzer
|
|
Registriert seit: Mar 2009
Beiträge: 177
|
|
@fireweasel
Hallo, dein tipp mit dem foreach funktioniert hier nicht, hier das script und die fehlermeldung von php:
PHP-Code:
<?php
$d=$_SERVER['DOCUMENT_ROOT']."/datei.log";
$arr=file($d);
foreach(array_slice($arr,-3) as & $zeile) # <= Fatal error: Cannot create references to elements of a temporary array expression
{$zt=explode('|', trim($zeile));
echo "<br>".$zeile;
}
?>
|

03-07-2009, 01:50
|
wahsaga
 Moderator
|
|
Registriert seit: Sep 2001
Beiträge: 24.486
|
|
Zitat:
Zitat von RamonaS
PHP-Code:
foreach(array_slice($arr,-3) as & $zeile) # <= Fatal error: Cannot create references
# to elements of a temporary array expression
|
Es kann an dieser Stelle nicht mit Referenzen gearbeitet werden, weil das Array keine reale Variable ist, sondern nur ein "flüchtiger" Wert, weil es die Rückgabe eines Funktionsaufrufes ist.
Also entweder auf die Nutzung von Referenzen an der Stelle verzichten (besteht hier eh keine Notwendigkeit zu), in dem man das & vor $zeile entfernt; oder das slicen vor der Schleife machen, und Ergebnis in einer Variablen ablegen.
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
|

03-07-2009, 13:49
|
|
RamonaS
Registrierter Benutzer
|
|
Registriert seit: Mar 2009
Beiträge: 177
|
|
Hallo,
Ok das hab ich jetzt auch verstanden. Mal schauen was ich das an der stelle mache.
Es muß halt ganz schnell die letzten 3 zeilen eine datei geprüft werden die so um die 450 kb hat.
Frage zu diesem hier:
PHP-Code:
$d=$_SERVER['DOCUMENT_ROOT']."/datei.log";
$arr=file($d);
kann ich das problemlos mit dieser zeile ersetzen?
PHP-Code:
$arr=explode("\n",file_get_contents($_SERVER['DOCUMENT_ROOT']."/datei.log"));
|

03-07-2009, 16:14
|
|
|
Ich möchte mal darauf hinweisen, das nicht unbedingt eine Code - Kurzform eine bessere Performance bringt, der Schuss kann auch ordentlich nach hinten los gehen.
Im Zweifelsfalle sollte man mehrere Varianten in einer Schleife ein paar tausend Mal durchlaufen lassen und die Zeit nehmen.
Alles andere ist nicht sinnvoll, da, was Performance betrifft sogar die PHP Version eine Rolle spielt.
Am besten wäre es einen Profiler benutzen (so mache ich es).
Bei Dingen die in einem Script nur ein einziges Mal vorkommen reden wir allerdings um die 6 te oder 7 Kommastelle was diese Aufgabe betrifft und die kann sogar noch tüchtig schwanken.
Es lohnt dann überhaupt nicht eine große Diskussion anzufangen.
|

03-07-2009, 16:14
|
wahsaga
 Moderator
|
|
Registriert seit: Sep 2001
Beiträge: 24.486
|
|
Zitat:
Zitat von RamonaS
Es muß halt ganz schnell die letzten 3 zeilen eine datei geprüft werden die so um die 450 kb hat.
|
Das geht mit file/file_get_contents aber sowieso nicht "ganz schnell" - damit müssen immer erst mal die 450 KB voll in den Speicher geschaufelt werden.
Wenn man an der Stelle was optimieren will, sollte man erst mal klären, ob häufiger gelesen oder geschrieben werden muss.
Wenn das Lesen die häufigere Aktion ist - dann sollte man vielleicht neue Datensätze immer an den Anfang der Datei schreiben.
Dann braucht man nur die ersten drei Zeilen auslesen, und kann danach aufhören und die Datei wieder zumachen.
Das erkauft man sich dann damit, dass das Schreiben der aufwendigere Prozess wird - da muss man dann den kompletten Dateiinhalt einlesen, hinter den neuen Datensatz hängen, und alles wieder zurückschreiben.
Wenn man letzteres nicht in Kauf nehmen will, dann könnte man auch zweigleisig fahren - die letzten drei Datensätze werden noch mal in einer eigenen Datei vorgehalten, wo man sie schnell und platzsparend herauslesen kann. Beim Schreiben eines neuen Datensatzes werden dieser und die neuesten zwei dieser drei wieder in die Datei geschrieben, der älteste verworfen; und gleichzeitig der neue an die grosse Datei angehangen wie bisher.
Das verkompliziert dich Sache aber natürlich um einiges, es wird deutlich aufwendiger dafür zu sorgen, dass der Stand in beiden Dateien konsitent bleibt.
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
|

03-07-2009, 17:12
|
|
|
Um mal zu zeigen von was man redet hier mal ein kleiner Testcode:
PHP-Code:
<?php $max=10000; echo '<h2>Start file_get_contents</h2>'; $j=0; while($j < 10) { $i=0; $starttime = microtime(true); while($i < $max) {
$daten=explode("\n",file_get_contents('test.txt')); $i++; } $gesamt = microtime(true) - $starttime; echo "<p>$gesamt</p>"; $j++; }
echo '<h2>Start fopen fgets</h2>'; $j=0; while($j < 10) { $i=0; $starttime = microtime(true); while($i < $max) {
$handle = fopen ("test.txt", "r"); $buffer=''; while (!feof($handle)) { $buffer .= fgets($handle, 4096); } fclose ($handle); $daten=explode("\n",$buffer); $i++; } $gesamt = microtime(true) - $starttime; echo "<p>$gesamt</p>"; $j++; }
echo '<h2>Start fopen fread</h2>'; $j=0; while($j < 10) { $i=0; $starttime = microtime(true); while($i < $max) {
$handle = fopen ("test.txt", "r"); $buffer=fread ($handle, filesize ('test.txt')); fclose ($handle); $daten=explode("\n",$buffer); $i++; } $gesamt = microtime(true) - $starttime; echo "<p>$gesamt</p>"; $j++; }
?>
Es wird dabei 3 mal je 100.000 mal eine Datei geöffnet, gelesen und als Array überführt.
Die Zeiten bei mir:
Start file_get_contents
0.31791687011719
0.2163360118866
0.21525907516479
0.22082805633545
0.21642589569092
0.21511697769165
0.2159378528595
0.21596598625183
0.21613693237305
0.21562886238098
Start fopen fgets
0.39897799491882
0.40530800819397
0.40406012535095
0.40339303016663
0.40501809120178
0.40479707717896
0.40492486953735
0.40336203575134
0.40440487861633
0.40475487709045
Start fopen fread
0.2047860622406
0.20500421524048
0.20504713058472
0.20702600479126
0.20528602600098
0.20522809028625
0.20636892318726
0.20539808273315
0.21517419815063
0.2058629989624
Es kommt da eigentlich nur fopen mit fread oder file_get_contents in Frage.
Der Code file_get_contents ist kürzer, aber tatsächlich langsamer.
Aber was heisst hier langsamer.
Man errechne die jeweils beste Differenz zu Gunste fread und teile das durch 100.000.
Da bleibt rein nichts mehr übrig über das man diskutieren müsste.
Wenn ich das nun auf die gepostete Eingangsfrage beziehe ist das eine reine Beschäftigungstherapie.
|

03-07-2009, 17:38
|
wahsaga
 Moderator
|
|
Registriert seit: Sep 2001
Beiträge: 24.486
|
|
Zitat:
Zitat von piratos
Da bleibt rein nichts mehr übrig über das man diskutieren müsste.
|
Das war mir klar, aber die Eingangsfrage war ja auch nicht meine.
Grundsätzlich gilt beim Entwickeln erst mal, "Performanceprobleme werden dann angegegangen, wenn sie auftreten, und nicht vorher."
Aber das heisst natürlich nicht, dass man nicht auch vorher schon mal ein paar theoretische Überlegungen anstellen und potentielle Flaschenhälse identifizieren und ggf. gleich vermeiden kann.
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
|

03-07-2009, 17:54
|
|
|
Zitat:
Zitat von wahsaga
Das war mir klar, aber die Eingangsfrage war ja auch nicht meine.
|
Auch klar.
Wenn ich das richtig sehe geht es bei der Fragestellerin um ein Problem was hier bereits auf mehrere Postings verteilt behandelt wird.
Sie sollte ganz simple meine Beispielroutine nehmen und ihre Gedankengänge in Testeinheiten fassen und schauen was da raus kommt, wenn Sie der Meinung ist es lohne sich um ein paar Mikrosekunden Stunden zu forschen.
Das kann sie dann ganz leicht selbst heraus finden.
Ich meine das als Anleitung zu Selbsthilfe.
Der Vorschlag
Zitat:
|
$counter = sprintf("%06d", $counter);
|
ist bedeutend schneller.
So etwas (wurde aber bereits von anderen gesagt):
Zitat:
if(count($arr)>2) # Nur die letzten 3 Dateizeilen prüfen
{for($i=2;$i>=0;--$i)
{$z=explode("|",trim($arr[count($arr)-$i-1]));
...
}
}
|
ist programmtechnischer Unsinn da count bei jedem Schleifenduchgang ausgelöst wird und somit alles langsamer macht, wie auch foreach fixer ist.
Ich empfehle der Fragestellerin sich auch mal mit dem PHP Manual zu beschäftigen, da wird unterhalb der Erklärungen von vielen PHP Kennern noch guter Beispielcode geliefert.
|

03-07-2009, 18:58
|
|
RamonaS
Registrierter Benutzer
|
|
Registriert seit: Mar 2009
Beiträge: 177
|
|
Danke an piratos für das test-script.
Ok damit sieht man das es im erstfall eigentlich egal ist welche form man in diesem falle wählt...das ergebnis bezieht sich ja dann noch auf 100000 durchgänge, ich habe eigentlich 1 durchgang beim lesen/ prüfen + 1 durchgang beim schreiben.
Und wie warsaga schon gesagt hat - ich möchte natürlich einige flaschenhälse vermeiden - deshalb stell ich euch auch immer wieder so komische fragen...ich bohr gehrne rum und möchte - so weit das möglich ist - das beste aus den scripten rausholen.
Ja, ich mag sehr kurzen code/zeilen lieber, ich denk da auch an Morgen, falls ich da wieder ran muß und dann sollte ich noch verstehen was das script detailliert so tut.
PHP-Code:
if(count($arr)>2) # Nur die letzten 3 Dateizeilen prüfen
{for($i=2;$i>=0;--$i)
{$z=explode("|",trim($arr[count($arr)-$i-1]));
...
}
}
Ja das waren meine anfängerfehler...da hab ihr mir ja gesagt was zu tun ist.
Also lese ich count() jetzt ausserhalb der schleife, dann wurde mir gesagt ++$i; ist etwas schneller als $i++; und bei arrays lieber foreach als for-schleife.
Na?...ich mach mich doch oder?
Ok dann mal ein herzliches Dankeschön an alle beteiligten und ein schönes Wochende (falls mir nicht doch noch paar neue Frage einfallen).
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|