Dodwin: Eigene Timestamps erstellen?

Hallo alle zusammen und miteinander,

Ich möchte in möglichst kurzer Zeit möglichst viele Einträge auswerten.
Auswerten bedeutet in diesem Fall vereinfacht Wochentag rausfinden und timestamp berechnen für eine spätere Datumsanzeige.
Geben sind dazu bei jedem Eintrag Jahr, Monat, Tag, Stunde, Minute, Sekunde.

Ich habe nun mit dem Wochentag angefangen und habe das so probiert:
$weekday = date('w',strtotime($year.'-'.$month.'-'.$day));

Leider war das sehr langsam und deshalb hab ich versucht diese Funktion nachzubauen.

Ich möchte euch aber nicht mit Code bombardieren [1] und komme sofort zu den Test-Ergebnissen:

Bei 100.000 Durchläufen brauchte die obengenannte Funktion im Durchschnitt 20.694 sec.
Die nachgebaute Funktion brauchte bei gleicher Anzahl an Durchläufen lediglich 0.514 sec im Durchschnitt.
Das bedeutet die nachgebaute Funktion ist ca 40x so schnell.

Also keine Frage ich nehme natürlich die nachgebaute Funktion.

Jetzt komme ich aber zum Timestamp und zur eigentlichen Frage:
Die Timestamp-Berechnung dauert ebenfalls sehr lange.
Nun habe ich auch diese Funktion (mktime oder wahlweise strtotime) versucht nachzubauen und siehe da sie war wieder schneller.

Leider musste ich aber enttäuscht feststellen, dass meine selbst erstellten timestamps teilweise um eine Stunde von den wirklichen Ergebnissen abwichen. Ich hatte die Sommer/Winter-Zeit vergessen.

Das macht die Sache leider kompliziert und nun habe ich mir überlegt wäre es nicht einfacher sich seine "eigenen" timestamps zu berechnen.

Die würden dann:
 - Die Zeit seit 1990 (nicht seit 1970) berechnen.
 => kleinere Zahlen (ältere Daten bekomme ich nicht)

- Die Sommer-/Winterzeit ignorieren.
 => Der Wert wäre dann zwar nicht ganz korrekt (wenn man die Sekunden seit 1990 angeben will), aber das Datum wäre in der Datumsangabe wieder richtig (wenn man davon ausgeht, dass Sommer/Winterzeit ignoriert wird).

Was meint ihr zu der Idee?

Danke für Anregungen und Antworten.

Gruß,
Dodwin

[1] Der Code zum Geschwindigkeits-Test:
    - nachgebaute Wochentag-Berechnung ~ 0.514 sec
    - normale Wochentag berechnung ~ 20.694 sec

--
Dodwin
  1. echo $begrüßung;

    Geben sind dazu bei jedem Eintrag Jahr, Monat, Tag, Stunde, Minute, Sekunde.

    Dann nimm doch einfach (gm)mktime(), wenn die Werte schon einzeln vorliegen, als sie mit Stringverknüpfung zusammenzufügen und wieder parsen zu lassen, noch dazu von einer Funktion, die verschiedene Darstellungen zu erraten versucht.

    Ich habe nun mit dem Wochentag angefangen und habe das so probiert:
    $weekday = date('w',strtotime($year.'-'.$month.'-'.$day));

    Über den Zeitverbrauch bei solch aufwendigen Operationen wundere ich mich nicht.

    echo "$verabschiedung $name";

  2. Hallo Dodwin,

    Ich habe nun mit dem Wochentag angefangen und habe das so probiert:
    $weekday = date('w',strtotime($year.'-'.$month.'-'.$day));

    Das ist - wie Dir bereits gesagt wurde - nicht die effizienteste Methode. Ein

    $weekday = idate ('w', mktime (0, 0, 0, $monats_nummer, $tag, $jahr));

    wäre schonmal effizienter. Dann kannst Du ja - weil Du nur Datumsberechnungen machst und Dich die Zeit nicht interessiert auf die gm-Funktionen setzen, d.h.

    $weekday = gmdate ('w', gmmktime (0, 0, 0, $monats_nummer, $tag, $jahr));

    Das wäre die effizienteste in PHP eingebaute Methode.

    Bei 100.000 Durchläufen brauchte die obengenannte Funktion im Durchschnitt 20.694 sec.

    Die Methode über idate() + mktime() ist bei mir nur leicht schneller als die Methode über date() + strtotime() - allerdings ist die Methode über gmdate() + gmmktime() bei mir nur noch 2 Mal so langsam, wie Deine Funktion. Zu den Hintergründen: Siehe unten.

    Die nachgebaute Funktion brauchte bei gleicher Anzahl an Durchläufen lediglich 0.514 sec im Durchschnitt.
    Das bedeutet die nachgebaute Funktion ist ca 40x so schnell.

    Leider ist Deine nachgebaute Funktion zum einen falsch und zum anderen nicht die effizienteste Implementierung selbst innerhalb des Wertebereichs, den Deine Funktion akzeptiert.

    Warum ist die Funktion falsch? Weil sie Schaltjahre nicht korrekt berücksichtigt. Du nimmst an, dass alle 4 Jahre in Schaltjahr ist. Dies ist nicht korrekt! Dies war im julianischen Kalender so, im gregorianischen Kalender (den wir aktuell verwenden) ist die Schaltjahresregel anders, nämlich: Alle 4 Jahre sind ein Schaltjahr, alle 100 Jahre wieder nicht, alle 400 Jahre dann doch wieder. Da das Jahr 2000 gerade in die 400-Jahre-Regelung fällt, stimmt Deine Funktion da zufälligerweise wieder, im Jahr 2100 stimmt sie dagegen nicht mehr.

    Zudem: Warum schränkst Du den Wertebereich der Funktion künstlich ein? Für Daten von vor 1990 liefert sie schlichtweg ein falsches Ergebnis, ohne es abzufangen und einen Fehler zurückzugeben.

    Wenn Du etwas selbst programmiertes nutzen willst:

    Eine Funktion zum Berechnen des Wochentags für den greorianischen und julianischen Kalender hatte ich bereits im Forum gepostet. Diese funktioniert für alle Daten ab dem 01.01.4713 v.u.Z. JC. Sie ist einen winzigen Tick ineffizienter als Deine Funktion, weil sie 4x die PHP-Funktion floor() aufruft - obwohl das nicht überall nötig wäre. Folgender Code nutzt nur noch (int) statt floor() - und gibt eine Zahl (0 für Montag etc.) statt eines Monatsnamens zurück. Ich habe die Kommentare zu den Berechnungen der Kürze wegen entfernt, die findest Du in dem obigen Archivposting:

    function wochentag ($jahr, $monat, $tag, $g = true) {  
     if ($monat <= 2) {  
      $jahr--;  
      $monat += 12;  
     }  
     if ($g) {  
      $jahrhundert = floor ($jahr / 100);  
      $korrektur = 2 - $jahrhundert + floor ($jahrhundert / 4);  
     } else {  
      $korrektur = 0;  
     }  
     $jul_tag_zahl = (int) (365.25 * ($jahr + 4716));  
     $jul_tag_zahl += (int) (30.6001 * ($monat + 1));  
     $jul_tag_zahl += $tag;  
     $jul_tag_zahl += $korrektur;  
     $jul_tag_zahl -= 1524;  
     return $jul_tag_zahl % 7;  
    }
    

    Oder (einen Tick effizienter) als fast geschlossener Ausdruck:

    function wochentag ($jahr, $monat, $tag, $g = true) {  
     if ($monat <= 2) {  
      $jahr--;  
      $monat += 12;  
     }  
     if ($g) {  
      $jahrhundert = floor ($jahr / 100);  
      $korrektur = 2 - $jahrhundert + floor ($jahrhundert / 4);  
     } else {  
      $korrektur = 0;  
     }  
     $jul_tag_zahl = (int) (365.25 * ($jahr + 4716))+ (int) (30.6001 * ($monat + 1)) + $tag + $korrektur - 1524;  
     return $jul_tag_zahl % 7;  
    }
    

    Oder man kann auf floor() komplett verzichten, ohne sich den Wertebereich kaputt zu machen (für negative Jahre ist (int) != floor!):

    function wochentag ($jahr, $monat, $tag, $g = true) {  
     if ($monat <= 2) {  
      $jahr--;  
      $monat += 12;  
     }  
     if ($g) {  
      $jahrhundert = (int) (($jahr + 4800) / 100) - 48;  
      $korrektur = 2 - $jahrhundert + (int) (($jahrhundert + 48) / 4) - 12;  
     } else {  
      $korrektur = 0;  
     }  
     $jul_tag_zahl = (int) (365.25 * ($jahr + 4716))+ (int) (30.6001 * ($monat + 1)) + $tag + $korrektur - 1524;  
     return $jul_tag_zahl % 7;  
    }
    

    Dies dürfte auch die effizienteste korrekte Implementierung in PHP sein, ist etwa 1,3x so schnell wie Deine Lösung, unterstützt sowohl den gregorianischen als auch den julianischen Kalender und ist korrekt für alle Daten ab dem 1. Januar 4713 v.U.Z. (das war vor etwa 6720 Jahren).

    Wenn Du also möglichst effizient lediglich die Wochentage berechnen willst, dann empfehle ich Dir die letzte Implementierung. Ich stelle mir allerdings auch hier wieder die Frage: Wozu? Wenn Du sowieso nur einen limitierten Zeitraum abbilden willst, dann reichen gmdate() + gmmktime() völlig aus - die sind zwar etwa 2,5x so langsam wie meine letzte Funktion, aber ich kann mir nicht vorstellen, dass das irgend etwas ausmacht. Wie oft berechnest Du denn Wochentage im Script?

    Die Timestamp-Berechnung dauert ebenfalls sehr lange.

    Was heißt für Dich "lange"? Ich wiederhole mich zwar, aber selbst Deine ursprünglichen Zahlen für die Wochentagsberechnung mit date() + strtotime() implizieren 0,21ms pro Berechnung - ich kann mir ehrlich nicht vorstellen, dass das der Flaschenhals in Deinem Script ist.

    Nun habe ich auch diese Funktion (mktime oder wahlweise strtotime) versucht nachzubauen und siehe da sie war wieder schneller.

    Leider musste ich aber enttäuscht feststellen, dass meine selbst erstellten timestamps teilweise um eine Stunde von den wirklichen Ergebnissen abwichen. Ich hatte die Sommer/Winter-Zeit vergessen.

    Das macht die Sache leider kompliziert

    Ja, Zeitzonen sowie Sommer- und Winterzeit sind eine ziemlich komplexe Angelegenheit. Zum Beispiel ist die Uhrzeit 02:30:00 am 30. März 2008 in unserer Zeitzone nicht erlaubt. Sie darf schlichtweg nicht vorkommen. Warum? Weil die Uhr am 30. März von 01:59:59 auf 03:00:00 umspringt. Genauso gibt es die Uhrzeit 02:30:00 am 28. Oktober 2007 gleich zwei Mal mit einer Stunde Abstand - laut Gesetz ist die erste Stunde als "A" und die zweite Stunde als "B" zu bezeichnen. Zudem kommt noch hinzu, dass es in anderen Ländern andere Vorschriften zur Umstellung gibt und diese wurden z.B. in den USA erst kürzlich geändert, d.h. vor 2006 galt die eine Regelung, danach die andere.

    Es gibt im Internet unter http://www.twinsun.com/tz/tz-link.htm eine Datenbank, die Public Domain ist, die erschöpfende Informationen über Zeitzonen und Sommer-/Winterzeit enthält. Wenn Du die wirklich verwendent willst, wird es allerdings schnell SEHR kompliziert.

    PHP macht das aber bereits für Dich, Du brauchst Dich nicht darum kümmern. Deswegen ist gmdate() / gmmktime() so viel schneller als date() / strtotime() - PHP muss bei GMT nicht schauen, welche Zeitzone / Sommer+Winterzeit da gilt oder nicht, GMT hat sowas per Definition nicht.

    und nun habe ich mir überlegt wäre es nicht einfacher sich seine "eigenen" timestamps zu berechnen.
    Die würden dann: [gekürzt]

    • Die Zeit seit 1990 (nicht seit 1970) berechnen.
    • Die Sommer-/Winterzeit ignorieren.
      Was meint ihr zu der Idee?

    Naja, wenn Du Sommer-/Winterzeit ignorieren willst, nimm gmdate() und gmmktime(). Die sind schon ausprogrammiert und definitiv nicht viel langsamer (evtl. sogar schneller [1]) als alle Funktionen, die Du selbst programmieren kannst. Ein eigenes Timestamp-Format einzuführen, das einen noch eingeschränkteren Wertebereich als das ursprüngliche hat, ist dagegen ziemlicher Quatsch - mit den Werten wird nämlich keiner umzugehen wissen.

    Wenn Du nur das Datum brauchst und Dir gm* immer noch zu langsam ist, dann könntest Du eine julianische Tageszahl [2] nehmen - das ist zumindest einen gängige Konvention. Wie Du eine julianische Tageszahl berechnest, siehst Du ja in der Funktion für den Wochentag (einfach das % 7 weglassen), das wieder Rückgängig zu machen ist ja nicht allzu schwierig (siehe Wikipedia).

    Andererseits (ja ich weiß, ich wiederhole mich) frage ich mich, was Du eigentlich im Script anstellst, um zu glauben, dass die normalen PHP-Datumsfunktionen ein Performanceproblem darstellen. Denn für ALLES, was ich bisher gesehen habe (und ich habe eine MENGE PHP-Code gesehen), waren die Funktionen LOCKER schnell genug.

    Viele Grüße,
    Christian

    [1] Bei der Wochentagsberechnung waren sie deswegen langsamer, weil sie dennoch die Uhrzeit mit berücksichtigten, obwohl das hier nicht nötig war.

    [2] Oder, um die Wikipedia-Terminologie zu nutzen: »Chronologisches Julianisches Datum« (das "normale" »julianische Datum« nutzt Zeit als Bruchanteil der Zahl - für reine Datumsberechnungen brauchst Du das aber nicht).

    1. Hallo Christian,

      Erst mal vielen Dank für diese ausführlichen Informationen.

      Ein
      $weekday = idate ('w', mktime (0, 0, 0, $monats_nummer, $tag, $jahr));
      wäre schonmal effizienter. [...]

      Nur bedingt leider, da mir der Monat als String (z.B. Sep) vorliegt. Ich muss also erst die Monatszahl für mktime herausfinden...

      Leider ist Deine nachgebaute Funktion zum einen falsch und zum anderen nicht die effizienteste Implementierung selbst innerhalb des Wertebereichs, den Deine Funktion akzeptiert.

      [...]Da das Jahr 2000 gerade in die 400-Jahre-Regelung fällt, stimmt Deine Funktion da zufälligerweise wieder, im Jahr 2100 stimmt sie dagegen nicht mehr.

      Die Funktion soll nur Werte von 1990 bis ca. 2020 (wenn überhaupt...) verarbeiten.

      Für diesen Zeitraum gibt die Funktion einen korrekten Wert aus (was nach 2100 ist interessiert mich doch nun wirklich nicht ;) )?

      Zudem: Warum schränkst Du den Wertebereich der Funktion künstlich ein? Für Daten von vor 1990 liefert sie schlichtweg ein falsches Ergebnis, ohne es abzufangen und einen Fehler zurückzugeben.

      Die Daten die ich erhalte sind Log-Daten. Es wird vorher überprüft ob fehlerhafte Einträge vorhanden sind (leere Zeilen, etc.). Bei der Wochentags-Funktion dürften keine Fehler ankommen. (jaja soweit die Theorie...)

      PHP macht das aber bereits für Dich, Du brauchst Dich nicht darum kümmern. Deswegen ist gmdate() / gmmktime() so viel schneller als date() / strtotime() - PHP muss bei GMT nicht schauen, welche Zeitzone / Sommer+Winterzeit da gilt oder nicht, GMT hat sowas per Definition nicht.

      Oh sehr schön, soweit hatte ich nicht gedacht. Die Funktionen sind wirklich nur minimal langsamer als "selbstgebastelte". Ich werde diese benutzen.

      Gruß,
      Dodwin

      --
      Dodwin
      1. Hallo Dodwin,

        Nur bedingt leider, da mir der Monat als String (z.B. Sep) vorliegt. Ich muss also erst die Monatszahl für mktime herausfinden...

        Ja gut, aber Du hast ja schon ein array_search in Deiner anderen Funktion. Und _das_ macht den Braten nicht fett. Noch schneller als array_search wäre übrigens das hier:

        $monate = array (  
           'Jan' => 1,  
           'Feb' => 2,  
           ...  
        );  
          
        $monat_num = $monate[$monat];
        

        (Liegt daran, dass ein Zugriff über den Array-Schlüssel viel häufiger schneller ist als den Array durchzugehen bis der erste Wert passt - wobei bei 7 Einträgen der Unterschied vmtl. minimal ist.)

        Die Funktion soll nur Werte von 1990 bis ca. 2020 (wenn überhaupt...) verarbeiten.

        Für diesen Zeitraum gibt die Funktion einen korrekten Wert aus[...]?

        Soweit ich das auf den ersten Blick sehen kann, ja. Allerdings möchte ich Dich auf eines aufmerksam machen: Wenn Du den Code jetzt schreibst, weißt Du vielleicht noch, was für Limitationen der hat - aber wenn Du sagen wir in 1 Jahr nochmal ne Wochentagsfunktion brauchst, dann riskierst Du, die Funktion einfach zu kopieren ohne darüber nachzudenken und dann fliegt sie Dir irgendwo anders um die Ohren. Daher sollte man - meiner Ansicht nach zumindest - *immer* zusehen, dass Funktionen, die man schreibt, möglichst korrekt sind - dann muss man sich bei der Wiederverwertung keine Gedanken machen. Zudem: Meine korrektere Funktion mit größerem Wertebereich wäre hier sowieso schneller. ;-)

        Die Daten die ich erhalte sind Log-Daten.

        Ok, dann leuchtet natürlich schon ein, dass Du *sehr* oft Timestamps erzeugen musst. Sag das doch gleich. ;-)

        Aber ernsthaft, wenn's Logfiles sind: Normalerweise steht doch bei Logfiles das Zeitzonenoffset mit dabei? Bei Apache-Logs in der Default-Config z.B. so: "[02/Oct/2007:19:43:24 +0200]" - das "+0200" ist ja das Offset zu GMT in der Form +HHMM (oder -HHMM). In dem Fall wäre die lokale Zeitzone anzunehmen sowieso falsch, um einen korrekten Timestamp zu erhalten müsstest Du sowieso gmmktime() auf den ersten Teil anwenden und dann das Offset in Sekunden auf den Timestamp addieren (oder subtrahieren, wenn's negativ ist).

        Viele Grüße,
        Christian

        1. Hallo Christian,

          (Liegt daran, dass ein Zugriff über den Array-Schlüssel viel häufiger schneller ist als den Array durchzugehen bis der erste Wert passt - wobei bei 7 Einträgen der Unterschied vmtl. minimal ist.)

          Ja, werde ich so machen.

          Soweit ich das auf den ersten Blick sehen kann, ja. Allerdings möchte ich Dich auf eines aufmerksam machen: Wenn Du den Code jetzt schreibst, weißt Du vielleicht noch, was für Limitationen der hat - aber wenn Du sagen wir in 1 Jahr nochmal ne Wochentagsfunktion brauchst, dann riskierst Du, die Funktion einfach zu kopieren ohne darüber nachzudenken und dann fliegt sie Dir irgendwo anders um die Ohren. [...]

          Wobei man ja deshalb seinen Code kommentieren sollte.

          // Gibt nur gültige Werte von 1990 bis 2100
          und schon wüsste man Bescheid.

          Zudem: Meine korrektere Funktion mit größerem Wertebereich wäre hier sowieso schneller. ;-)

          Ähhmm... Hast du mit der Hand gestoppt? ;)

          Im Vergleich meines Wochentag-Codes und deiner Funktion:wochentag ($jahr, $monat, $tag, $g = true) mit (int)-Berechnung ist das erstere schneller.
          Ich nehme an du hast im Vergleich nicht die gleichen Bedingungen gehabt. Meine Funktin hat's mit $month = 'Sep'; gemacht und deine mit $month = 9; (tippe ich jetzt mal).

          Aber ernsthaft, wenn's Logfiles sind: Normalerweise steht doch bei Logfiles das Zeitzonenoffset mit dabei? Bei Apache-Logs in der Default-Config z.B. so: "[02/Oct/2007:19:43:24 +0200]" - das "+0200" ist ja das Offset zu GMT in der Form +HHMM (oder -HHMM). In dem Fall wäre die lokale Zeitzone anzunehmen sowieso falsch, um einen korrekten Timestamp zu erhalten müsstest Du sowieso gmmktime() auf den ersten Teil anwenden und dann das Offset in Sekunden auf den Timestamp addieren (oder subtrahieren, wenn's negativ ist).

          Gute Idee. Wobei es ja nur um die Datumsanzeige geht und somit werde ich nur auf die gm-Funktinoen zurückgreifen (vor allem beim Anzeigen wird's schneller gehn...).

          Gruß,
          Dodwin

          --
          Dodwin
          1. Hallo Dodwin,

            Zudem: Meine korrektere Funktion mit größerem Wertebereich wäre hier sowieso schneller. ;-)

            Ähhmm... Hast du mit der Hand gestoppt? ;)

            Nein. ;-)

            Ich habe folgendes genutzt:

            <?php  
              
            function start_timer() {  
              GLOBAL $script_start_time;  
              $microtime=explode(" ", microtime());  
              $script_start_time=$microtime[1]+$microtime[0];  
            }  
              
            function stop_timer($stellen) {  
              GLOBAL $script_start_time;  
              $microtime = explode(" ", microtime());  
              $script_stop_time = $microtime[1]+$microtime[0];  
              return number_format(($script_stop_time-$script_start_time),$stellen);  
            }  
              
            function wochentag ($year, $month_num, $day) {  
              
              $dif = $year - 1990;                        // 1. Jan 1990 war ein Montag  
              $leap_year_dif = $dif;                      // Anzahl der Schaltjahre herausfinden  
              if ($month_num > 2) $leap_year_dif++;       // ...  
              $leap_year = ceil(($leap_year_dif-2)/4);    // ...  
              $dif = $dif*365 + $leap_year;               // Tage berechnen  
              if ($month_num > 1) $dif += 31;             // Tage für Monate dazurechnen  
              if ($month_num > 2) $dif += 28;  
              if ($month_num > 3) $dif += 31;  
              if ($month_num > 4) $dif += 30;  
              if ($month_num > 5) $dif += 31;  
              if ($month_num > 6) $dif += 30;  
              if ($month_num > 7) $dif += 31;  
              if ($month_num > 8) $dif += 31;  
              if ($month_num > 9) $dif += 30;  
              if ($month_num > 10) $dif += 31;  
              if ($month_num > 11) $dif += 30;  
              if ($month_num > 12) $dif += 31;  
              $dif += $day-1;                             // Tag dazurechnen  
              
              return ($dif % 7);                      // Wochentag ausrechnen  
            }  
              
            start_timer();  
              
            /////////////////////////////// Beginn der Wochentag-Berechnung  
              
            $year = 2007;  
            $month_num = 9;  
            $day = 20;  
              
            for ($i=0;$i<1000000;$i++) {  
              $weekday = wochentag ($year, $month_num, $day);  
            }  
              
            /////////////////////////////// 0 => Montag  
            /////////////////////////////// 1 => Dienstag  
            /////////////////////////////// ...  
            /////////////////////////////// 6 => Samstag  
              
            /////////////////////////////// Ende der Wochentag-Berechnung  
              
            echo stop_timer(9);  
              
            ?>
            

            Meine Funktion:

            <?php  
              
            function start_timer() {  
              GLOBAL $script_start_time;  
              $microtime=explode(" ", microtime());  
              $script_start_time=$microtime[1]+$microtime[0];  
            }  
              
            function stop_timer($stellen) {  
              GLOBAL $script_start_time;  
              $microtime = explode(" ", microtime());  
              $script_stop_time = $microtime[1]+$microtime[0];  
              return number_format(($script_stop_time-$script_start_time),$stellen);  
            }  
              
            start_timer();  
              
            function wochentag ($jahr, $monat, $tag, $g = true) {  
             if ($monat <= 2) {  
              $jahr--;  
              $monat += 12;  
             }  
             if ($g) {  
              $jahrhundert = (int) (($jahr + 4800) / 100) - 48;  
              $korrektur = 2 - $jahrhundert + (int) (($jahrhundert + 48) / 4) - 12;  
             } else {  
              $korrektur = 0;  
             }  
             $jul_tag_zahl = (int) (365.25 * ($jahr + 4716))+ (int) (30.6001 * ($monat + 1)) + $tag + $korrektur - 1524;  
             return $jul_tag_zahl % 7;  
            }  
              
            $year = 2007;  
            $month = 9;  
            $day = 20;  
              
            for ($i=0;$i<1000000;$i++) {  
              $weekday = wochentag ($year, $month, $day);  
            }  
              
            echo stop_timer (9);  
              
            ?>
            

            Zwei Unterschiede zu Deinem Code: Ich habe bei BEIDEN nur die Monatsnummer verwendet (das array_search käme bei beidne dazu und wäre deswegen eine konstante Zeit und nicht hilfreich zum Vergleichen der reinen Laufzeit des unterschiedlichen Codes) und Deinen Teil habe ich auch in eine Funktion gepackt, so wie es im tatsächlichen Code dann wohl auch genutzt würde. Achja, und ich hab 1 Mio statt nur 100 tausend Aufrufe. Ergebnis:

            Meine Version: 2.517229080 Sekunden
            Deine Version: 3.288582802 Sekunden

            System: Pentium M mit 2 GHz, 512 MiB RAM, PHP 5.2.1-pl3-gentoo (cli) (built: May  6 2007 17:39:57).

            Und wenn ich BEIDES direkt reinkopiere (ohne Funktion), dann erhalte ich:

            Deine Version: 2.056279898s
            Meine Version (1): 1.149389029s
            Meine Version (2): 1.048664093s

            Bei (2) habe ich noch zusätzlich das if ($g) entfernt, da Du ja sowieso nur den gregorianischen Kalender willst.

            Klar, wenn Du Deinen Code direkt reinkopiert testest und bei mir den Funktionsaufruf durchführst (kostet Zeit!), dann ist es natürlich logisch, dass Dein Code schneller ist. Wenn ich aber bei BEIDEN gleiche Bedingungen schaffe (d.h. nur den Code teste, der wirklich relevant ist bzw. bei BEIDEN den gleichen Zusätzlichen Code wie Funktionsaufruf reinpacke), dann ist meine Version schneller - und zwar fast doppelt so schnell und das bei größerem Gütligkeitsbereich.

            Viele Grüße,
            Christian

            1. Hallo Christian,

              Meine Version: 2.517229080 Sekunden
              Deine Version: 3.288582802 Sekunden

              Ja, ich muss mich geschlagen geben. ;)
              Meine Versuche kommen zu annähernd dem gleichen Ergebnis.
              Deine Funktion ist wirklich schneller.

              Ich hätte nicht gedacht, dass es so viel Zeit kostet, wenn man es in eine eigene Funktion packt (wobei viel Zeit hier auch weniger als 1/100 Millisekunde bedeutet).

              Gruß,
              Dodwin

              --
              Dodwin