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