Diesen Code optimieren?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • 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]));
        ... 
       }
     } 
    ACHTUNG: RamonaS zeigte ein beschämendes Verhalten in der Vergangenheit

  • #2
    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.
    [FONT="Helvetica"]twitter.com/unset[/FONT]

    Shitstorm Podcast – Wöchentliches Auskotzen

    Kommentar


    • #3
      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));
          ...  
         } 
       } 
      Zuletzt geändert von deedee; 24.06.2009, 21:57.

      Kommentar


      • #4
        Zitat von RamonaS Beitrag anzeigen
        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); 

        Kommentar


        • #5
          Zitat von RamonaS Beitrag anzeigen
          ... 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:
          Zuletzt geändert von fireweasel; 03.07.2009, 12:27.
          Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

          Kommentar


          • #6
            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

            ACHTUNG: RamonaS zeigte ein beschämendes Verhalten in der Vergangenheit

            Kommentar


            • #7
              @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;
               }
              ?>
              ACHTUNG: RamonaS zeigte ein beschämendes Verhalten in der Vergangenheit

              Kommentar


              • #8
                Zitat von RamonaS Beitrag anzeigen
                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.

                Kommentar


                • #9
                  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")); 
                  ACHTUNG: RamonaS zeigte ein beschämendes Verhalten in der Vergangenheit

                  Kommentar


                  • #10
                    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.

                    Kommentar


                    • #11
                      Zitat von RamonaS Beitrag anzeigen
                      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.

                      Kommentar


                      • #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($handle4096);
                          }
                            
                        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 ($handlefilesize ('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.

                        Kommentar


                        • #13
                          Zitat von piratos Beitrag anzeigen
                          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.

                          Kommentar


                          • #14
                            Zitat von wahsaga Beitrag anzeigen
                            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

                            [COLOR=#000000][COLOR=#0000CC]$counter [/COLOR][COLOR=#006600]= [/COLOR][COLOR=#0000CC]sprintf[/COLOR][COLOR=#006600]([/COLOR][COLOR=#CC0000]"%06d"[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]$counter[/COLOR][COLOR=#006600]); [/COLOR][/COLOR]
                            ist bedeutend schneller.

                            So etwas (wurde aber bereits von anderen gesagt):
                            [COLOR=#000000][COLOR=#006600]if([/COLOR][COLOR=#0000CC]count[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$arr[/COLOR][COLOR=#006600])>[/COLOR][COLOR=#0000CC]2[/COLOR][COLOR=#006600]) [/COLOR][COLOR=#FF9900]# Nur die letzten 3 Dateizeilen prüfen
                            [/COLOR][COLOR=#006600]{for([/COLOR][COLOR=#0000CC]$i[/COLOR][COLOR=#006600]=[/COLOR][COLOR=#0000CC]2[/COLOR][COLOR=#006600];[/COLOR][COLOR=#0000CC]$i[/COLOR][COLOR=#006600]>=[/COLOR][COLOR=#0000CC]0[/COLOR][COLOR=#006600];--[/COLOR][COLOR=#0000CC]$i[/COLOR][COLOR=#006600])
                            {[/COLOR][COLOR=#0000CC]$z[/COLOR][COLOR=#006600]=[/COLOR][COLOR=#0000CC]explode[/COLOR][COLOR=#006600]([/COLOR][COLOR=#CC0000]"|"[/COLOR][COLOR=#006600],[/COLOR][COLOR=#0000CC]trim[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$arr[/COLOR][COLOR=#006600][[/COLOR][COLOR=#0000CC]count[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$arr[/COLOR][COLOR=#006600])-[/COLOR][COLOR=#0000CC]$i[/COLOR][COLOR=#006600]-[/COLOR][COLOR=#0000CC]1[/COLOR][COLOR=#006600]]));
                            ...
                            }
                            } [/COLOR][/COLOR]
                            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.

                            Kommentar


                            • #15
                              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).
                              ACHTUNG: RamonaS zeigte ein beschämendes Verhalten in der Vergangenheit

                              Kommentar

                              Lädt...
                              X