[PHP] Code optimieren



  • Dann hast du wahrscheinlich Pech gehabt. Du hast doch nicht wirklich gedacht, dass wenn du bösestes File I/O machst, dass du dann an anderer Stelle noch unglaublich viel rausholen kannst? Optimieren kannst du nur dort, wo es wirklich langsam ist.



  • Vielleicht diese Datei auf nen server packen, wo du ne DB zur verfügung hast (funpic.de z.B. ist auch noch kostenlos + werbefrei)


  • Mod

    CSS schrieb:

    Aber, ich habe keine zur Verfügung!

    Wage ich zu bezweifeln. Und wenn das wirklich so ist, dann wechsle den Hoster.

    kleiner Tip:
    http://de.php.net/manual/en/ref.dba.php



  • @-FOO_
    Auf dem koolhost.de- Server habe ich 3 DB's zur Verfügung,. allerdings war der sehr oft down und ich möchte von keinem anderen Server abhängig sein.
    @Shade of Mine
    Ich kann den Hoster nicht wechseln, du wirst dich vielleicht wundern aber es geht immer noch um die Website der Schule.

    MfG CSS


  • Mod

    CSS schrieb:

    Ich kann den Hoster nicht wechseln, du wirst dich vielleicht wundern aber es geht immer noch um die Website der Schule

    Und kein dba installiert? tja, dann hast du ein problem...

    die ganze datei immer einlesen ist lahm. du musst also selber ne DB implementieren, also schau dir mal http://sourceforge.net/projects/flatfiledb/ an. vielleicht ist das schnell genug, ich selber habe damit noch nicht gearbeitet, der ansatz sieht aber gut aus.

    wenn das nicht geht, dann musst du ein index file aufbauen... uU ist es auch nicht verkehrt fuer jede ip ne eigene datei anzulegen... das koennte verdammt schnell sein, wenn der server ein gutes fs hat, zB reiser. wenn nicht, dann wirds verdammt lahm. (hab zB winnt4 letzte woche mit 40.000 dateien 'abgeschossen' die performance war hart an der grenze - also wenn du ein schlechtes fs und verdammt viele user hast, vergiss das).

    moeglich waere es aber die ips nach bereichen zu ordnen, so hast du kleinere dateien zum durchsuchen und wenig dateien...

    und gehe ich recht in der annahme dass die 1. schleife ein gc ist? wenn ja -> probability gc verwenden oder besser cronjob.

    die schleifen muessen zusammengezogen werden, du rennst ja die dateien mehrmals durch...

    und die 1. schleife sieht sowieso irgendwie falsch aus... ich wuerde sie so schreiben:

    for($i=0, $c=count($read_ip); $i < $c; ++$i)
    {
        $timestamp = explode('#', $read_ip[$i]);
    
        if (trim($timestamp[1]) + $max_time*60 < time())
        {
            unset($read_ip[$i]);
        }
    }
    file_put_contents('users_ip.log', $read_ip);
    file_put_contents('was_online.log', count($read_ip));
    

    wie gesagt, das ganze halt nicht bei jedem aufruf...

    dann kann man aus der anderer schleife ein

    $ips = file('users_ip.log');
    
    for($i=0,$c=count($ips); $i<$c; ++$i)
    {
        $old_ip = explode('#', $ips[$i]);
        $old_ip = trim($old_ip[0]);
    
        if ($old_ip == $user_ip)
        {
            $has_already_visited = TRUE;
            break;
        }
    }
    

    und schon wieder n bisschen schneller...

    dann noch am schluss

    if ($has_already_visited === FALSE)
    {
        $aufruf = file_get_contents('was_online.log');
        ++$aufruf;
        file_put_contents('was_online.log', $aufruf);
    
        $timestamp = "#" . time() . "\r\n";
    
        $f = fopen('users_ip.log', 'a');
        fwrite($f, $user_ip.'#'.$timestamp);
        fclose($f);
    }
    if(!isset($aufruf))
      $aufruf=file_get_contents('was_online.log');
    

    dann hast du die anzahl der besucher bereits in $aufruf stehen und musst nicht mehr extra file_get_contents aufrufen...

    wie gesagt: pack noch die einteilung in mehrere dateien dazu, dann dauert der gc zwar laenger, aber das scannen nach einer IP kann extrem verkuerzt werden.

    der gc wird nicht mehr jedesmal aufgerufen, sondern nur noch ganz selten und gut ist.

    das ganze prinzip ist mir dennoch nicht klar: was macht was_online.log? es hat den anschein als wuerde es die gesamtanzahl der aufrufe darstellen, aber in wirklichkeit sind es nur die anzahl der 'validen' user die online sind.

    aber das 'online' sein definiert sich durch das einloggen nicht durch die letzte aktion... das verwirrt etwas... weil dadurch was_online irgendwie keinen sinn ergibt.



  • Okay, danke.
    was_online.log => were_online.log
    Da in were_online.log die Zahl der User die die Seite besucht haben steht. (schwerer gramatikalischer Fehler!)

    Ja ich hab' den Counter ohne viel zu überlegen programmiert, als mir dann aber aufgefallen ist, dass er so verdammt langsam ist (sogar mit ADSL) hab' ich gleich mal den Post geschrieben.

    EDIT:
    Muss es nicht $i++ heißen? Da ein Array ja bei 0 beginnt.
    Also:

    $ips = file('users_ip.log');
    
    for($i=0,$c=count($ips); $i<$c; $i++)
    {
        $old_ip = explode('#', $ips[$i]);
        $old_ip = trim($old_ip[0]);
    
        if ($old_ip == $user_ip)
        {
            $has_already_visited = TRUE;
            break;
        }
    }
    

    EDIT:
    Das war ja eine PHP 5 Varaiante des Counters, der Webserver unterstützt allerdings nur PHP 4 deshalb fällt file_put_contents() und file_get_contents() weg. Also: noch langsamer

    MfG CSS


  • Mod

    CSS schrieb:

    Da in were_online.log die Zahl der User die die Seite besucht haben steht.

    dann darfst du sie doch im GC nicht wieder verringern, oder?

    Ja ich hab' den Counter ohne viel zu überlegen programmiert, als mir dann aber aufgefallen ist, dass er so verdammt langsam ist (sogar mit ADSL) hab' ich gleich mal den Post geschrieben.

    Hat doch nix mit deiner Leitung zu tun...

    Muss es nicht $i++ heißen? Da ein Array ja bei 0 beginnt.

    egal wie du es drehst oder wendest, nach dem statement
    ++iundi und i++
    hat $i immer den selben wert.

    nur dass ++$i eben schneller 🙂

    Das war ja eine PHP 5 Varaiante des Counters, der Webserver unterstützt allerdings nur PHP 4 deshalb fällt file_put_contents() und file_get_contents() weg. Also: noch langsamer

    file_get_contents hast du auch schon in php4, ab 4.3 oder so.
    und soviel langsamer wirds dann ja auch nicht werden, weil file_*_contents ja auch nicht zaubern kann. klar etwas besser ist es schon, aber kannst ja notfalls mit stream_* noch ein bisschen tweaken, sollte aber nicht noetig sein.

    du verlierst ja durch ein fwrite/fread nicht soviel zeit - das ist micro optimierung.



  • Wird bei ++$i die Variable $i nicht zuerst inkrementiert und bei $i++ erst beim 2 Durchlauf?

    Achja, file_get_contents() gibt es sei PHP 4 , aber file_put_contents erst seit PHP 5.

    Was ist bitte GC ? (bin Anfänger)

    EDIT:
    $max_time wird wenn der Counter fertig ist bzw. zum Einsatz kommt auf 2880 (2 Tage) gestellt, damit keiner ausgeschlossen wird. Die Ip Methode dient eigentlich nur dazu, dass sich Schüler keinen Spaß erlauben und die Seite 100terte Male neu laden .Ich habe mir auch überlegt den Counter mit Cookies zu programmieren allerdings werde ich nocht abwarten wie sich der Trend Cookies abzuschalten entwickelt.

    PS: Ich werde für einige Monate auch einen versteckten professionellen Counter einsetzen um zu sehen in wie weit die Ergebnisse meines Counters von denen des anderen Counters abweichen.
    MfG CSS


  • Mod

    CSS schrieb:

    Wird bei ++$i die Variable $i nicht zuerst inkrementiert und bei $i++ erst beim 2 Durchlauf?

    ne ++iisteinstatementundwirdfuersichalleineevaluiert.for(i ist ein statement und wird fuer sich alleine evaluiert. for(a;b;b;c) d;istdasselbewied; ist das selbe wie a;
    while(b) { d;
    $c;
    }

    Was ist bitte GC ? (bin Anfänger)

    garbage collector. das ding, was die zu alte daten aus user_ips.log loescht.
    also deine erste schleife.

    die muss nicht jedesmal laufen, es reicht wenn sie jedes 100. mal oder so laeuft (je nachdem wieviel besucher da sind) - da bietet sich eine probability technik an -> bei jedem aufruf gibt es eine wahrscheinlichkeit von 1:100 dass der GC gestartet wird, so hast du recht leicht bei jedem 100tes durchlauf eine aufraeumaktion.

    $max_time wird wenn der Counter fertig ist bzw. zum Einsatz kommt auf 2880 (2 Tage) gestellt, damit keiner ausgeschlossen wird. Die Ip Methode dient eigentlich nur dazu, dass sich Schüler keinen Spaß erlauben und die Seite 100terte Male neu laden

    jo, dann reicht es doch, wenn du einmal taeglich die zu alten daten raushaust, oder? muss nicht bei jedem durchlauf geschehen...



  • bei jedem aufruf gibt es eine wahrscheinlichkeit von 1:100 dass der GC gestartet wird, so hast du recht leicht bei jedem 100tes durchlauf eine aufraeumaktion.

    Hey ich bin 14 was erwartes du? 🙂
    Nein, jetzt im Ernst wie weiß das Script, dass es schon 100 Mal aufgerufen wurde? Einfach bei jedem Aufruf einen Wert in eine Datei schreiben?
    MfG CSS



  • Auch mit 14 solltest du jetzt eine Sache endgültig begreifen: Datei lesen/schreiben ist SAULAHM ! 😉 😃


  • Mod

    CSS schrieb:

    Hey ich bin 14 was erwartes du? 🙂
    Nein, jetzt im Ernst wie weiß das Script, dass es schon 100 Mal aufgerufen wurde?

    Das weiss es nicht. Der Trick liegt in der Statistik.

    Du ermittelst bei jedem Aufruf eine Zufallszahl von 1 bis 100. wenn es 100 ist, dann loescht du alle veralteten daten.

    das passiert natuerlich nicht alle 100 aufrufe, aber im schnitt passt es wieder, weil du eben bei einer wahrscheinlichkeit von 1:100 im durchschnitt bei jedem 100. aufruf 100 als ergebnis hast. es pendelt sich also irgendwie ein 🙂



  • Okay, danke für die Hilfe, so werde ich es machen.

    MfG CSS


Anmelden zum Antworten