[ erweiterte Suche ]
problem mit imagesetpixelNeues Thema eröffnenNeue Antwort erstellenDas Thema einem Freund empfehlenDas Thema druckenlocalhost kann nicht aufgerufen werden
Seite 1 von 1 [3 Beiträge]
AutorNachricht
Administrator 


Name: Marc
Geschlecht:
Anmeldedatum: 28.08.2004
Beiträge: 30241
Chats: 11081
Wohnort: Hennef


Meine eBay-Auktionen:
13.10.2009, 12:20


Hi,

wegen einem Blogartikel, habe ich mich dran gemacht und mal getestet, welche Art der Speicherung Prüfung von Filecaches am schnellsten ist (z.B. wenn man Datenbankabfragen zwischenspeichert, statt sie erneut auszuführen).

Bisher nutzte ich include() und wollte auf filemtime() / file_get_contents() wechseln, da es bei sehr häufigen include() und Dateiänderungen dazu führt, dass die Datei unfertig eingebunden wird. Und was passiert, wenn man eine unfertige php-Datei einbindet? Richtig es erscheint die allseits bekannt $end-Fehlermeldung. Das Benchmark bestätigt mich jetzt noch mal in meiner Entscheidung auf reine Textdateien zu wechseln.

Hier die getesteten Codes:
   Zitat:
/*
// version 1
// run: 0.247105841635
// run: 0.261900234224 refresh set to 10 seconds
// run: 0.256287105084 refresh set to 10 seconds
// run: 0.249131891729 refresh set to 30 seconds
// fastest run: 0.104637145996
// run: 0.234740469457 without refresh
// fastest run: 0.0934660434723
// run: 0.237568306923 without refresh / without clearstatcache()
// fastest run: 0.147907018661
$gentime = 0;
$data = array();
// cache file will be included if it exists
if (file_exists($filename)) {
include($filename);
}
// cache file will be created if didn't existed or refreshed all 2 seconds
if (!$data || $gentime + 86400 < $now) {
// read data (db query...)
$data = array(
'id' => 1111,
0 => 'long text',
1 => 'long text',
2 => 'long text with quotes',
);
// write cache file
// it is necessary to lock first and truncate afterwards to avoid including a
// partial php file (won't work in 100% of all cases as it is still possible
// to include it after truncating it!)
$h = @fopen($filename, 'a');
@flock($h, LOCK_EX);
@ftruncate($h, 0);
@fwrite($h, '<' . '?php $gentime = ' . $now . '; $data = unserialize(\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), serialize($data)) . '\'); ?' . '>');
@flock($h, LOCK_UN);
@fclose($h);
@umask(0000);
@chmod($filename, 0644);
}
// only for the benchmark to avoid caching
clearstatcache();
*/
/*
// version 2
// run: 0.217099111083
// run: 0.222138965129
// run: 0.220421209337 refresh set to 10 seconds
// run: 0.222239365575 refresh set to 30 seconds
// run: 0.219991838929 without refresh
// fastest run: 0.0898759365082
// run: 0.181516561508 without refresh / without clearstatcache()
// fastest run: 0.103751897812
$data = array();
// cache file will be included if it exists
if (file_exists($filename)) {
$data = @unserialize(file_get_contents($filename));
}
// cache file will be created if didn't existed or refreshed all 2 seconds
if (!$data || filemtime($filename) + 2 < $now) {
// read data (db query...)
$data = array(
'id' => 1111,
0 => 'long text',
1 => 'long text',
2 => 'long text with quotes',
);
// write cache file
// we do not need to lock, as unserialize results false if data set is corrupt
$h = @fopen($filename, 'w');
@fwrite($h, serialize($data));
@fclose($h);
@umask(0000);
@chmod($filename, 0644);
}
// only for the benchmark to avoid caching
clearstatcache();
*/
?>

Zuletzt bearbeitet von mgutt am 14.10.2009, 00:46, insgesamt einmal bearbeitet

Verfasst am: 14.10.2009, 00:45

Mir sind noch drei Varianten eingefallen:
   Zitat:
/*
// version 3
// run: 0.243602633478
// run: 0.245651497837 10 secs
// run: 0.233414025306 30 secs
// fastest run: 0.114813804626
$data = array();
$h = fopen($filename, 'a');
if (flock($h, LOCK_EX | LOCK_NB)) {
$data = @unserialize(file_get_contents($filename));
}
if (!$data || filemtime($filename) + 2 < $now) {
// read data (db query...)
$data = array(
'id' => 1111,
0 => 'long text',
1 => 'long text',
2 => 'long text with quotes',
);
// write cache file
ftruncate($h, 0);
fwrite($h, serialize($data));
umask(0000);
chmod($filename, 0644);
}
flock($h, LOCK_UN);
fclose($h);
// only for the benchmark to avoid caching
clearstatcache();
*/
/*
// version 4
// run: 0.188958084584
// run: 0.185067784788
// fastest run: 0.0628659725189
// cache file will be created if didn't existed or refreshed all 2 seconds
// we removed file_exists() as we expect in 99% of all cases that the file is
// existing and if not, file_get_contents() does the same for us
if (!($data = @file_get_contents($filename)) || ($data = @unserialize($data)) === false || filemtime($filename) + 2 < $now) {
// read data (db query...)
$data = array(
'id' => 1111,
0 => 'long text',
1 => 'long text',
2 => 'long text with quotes',
);
// write cache file
// we do not need to lock, as unserialize results false if data set is corrupt
$h = @fopen($filename, 'w');
@fwrite($h, serialize($data));
@fclose($h);
@umask(0000);
@chmod($filename, 0644);
}
// only for the benchmark to avoid caching
clearstatcache();
*/
/*
// version 5
// run: 0.0989973068235
// run: 0.0999602222446
// fastest run: 0.0978970527649
// our script results more than 100 hits per second, so we add a random
// switch to reduce usage of filemtime()
// if you run this script on a website, you have to count your daily impressions
// and decide how much filemtime() requests are needed to find the balance between
// cache actuality and interval. f.e.: you have a birthday data cache and you want
// to refresh it every 24 hours. your website results 100.000 impressions per day.
// i would choose 100 as a good random factor as there are 1.000 impressions left
// to refresh the cache. one of them should hit between 00:00 and 00:59 to result
// actual birthday data on the website (with factor 100 apprx. 42 impressions per
// hour can hit our random factor)
if (!($data = @file_get_contents($filename)) || ($data = @unserialize($data)) === false || (rand(0, 100) == 100 && filemtime($filename) + 2 < $now)) {
// read data (db query...)
$data = array(
'id' => 1111,
0 => 'long text',
1 => 'long text',
2 => 'long text with quotes',
);
// write cache file
// we do not need to lock, as unserialize results false if data set is corrupt
$h = @fopen($filename, 'w');
@fwrite($h, serialize($data));
@fclose($h);
@umask(0000);
@chmod($filename, 0644);
}
if (isset($h)) {
// only for the benchmark to avoid caching
clearstatcache();
}
*/

Verfasst am: 14.10.2009, 01:04

15% konnte ich damit rausholen, dass ich auf file_exists() verzichtet habe und file_get_contents() und serialize() getrennt habe. Auf file_exists() können wir getrost verzichten, wenn wir unseren Cache immer nutzen. In dem Fall übernimmt file_get_contents() den Job.

Eigentlich ist file_get_contents() langsamer als file_exists(), aber das kommt nicht zum Tragen, da in 99,9% der Fälle ja eine Cache-Datei vorhanden sein wird und die Prüfung mit file_exists() damit überflüssig wird.

Danach habe ich eine weitere Idee ausprobiert, in der ich mir die Seitenaufrufe einer Website zu nutze mache. Da jede Cache-Datei durch den Besucher selbst ausgelöst wir, führt auch jeder Seitenaufruf zur entsprechenden Prüfung der Dateien mit filemtime(). Da diese Funktion aber bekanntlich zu viel Performance kostet und die Cache-Dateien nicht bei jedem Seitenaufruf erneuert werden müssen, machen wir uns einen Zufallsfaktor zu Nutze. Dieser hat die letzte Abfrage dann noch mal um 50% beschleunigt!

Geht man beispielsweise von 100.000 Seitenaufrufen pro Tag aus, so resultieren diese 100.000 Aufrufe von filemtime(). Das wollen wir nicht, weshalb wir einfach den Faktor 1:100 ins Spiel bringen. Schon reduzieren wir die Häufigkeit, mit der filemtime() aufgerufen wird auf 1.000. Damit haben wir noch ca. 42 Aufrufe pro Stunde. Haben wir nun einen Cache, der nur alle 24 Std. aktualisiert werden soll, wie z.B. die Geburtstagsliste aller Mitglieder, reicht das vollkommen für eine akzeptable Aktualität des Datensatzes.

Es kann zwar gut sein, dass die Geburtstage erst um 00:10 Uhr aktualisiert werden, aber im Regelfall sollte das reichen. Falls nicht, müsste man hier mit einem Zeitrahmen arbeiten, wo die Impressionen zwischen 00:00 und 00:10 Uhr z.B. alle zur Aktualisierung des Caches führen. Bei 100.000 Seitenaufrufen pro Tag fallen damit ca. 167 Aufrufe auf diese besagten 10 Minuten. Das wäre also sogar noch besser, da nur 167x, statt 1.000x die Funktion filemtime() aufgerufen wird.

Wie man sieht, kann man in diesem Punkt so einiges optimieren. Zumindest sollte man von dem flock-Konstrukt abkommen, dass weder performant, noch Sicherheit bietet, da man flock wiederrum beim Einlesen der Daten benötigt. Und ich glaube nicht, dass es so gut sein kann, wenn man bei mehreren Cache-Dateien in einem Seitenaufruf ständig sperrt und entsperrt.

Allerdings weiß ich noch nicht, ob der Wegfall von flock() Probleme machen könnte beim parallen Schreiben von identischen Cache-Datensätzen, was ja durchaus bei parallel laufenden Prozessen zum Tragen kommen könnte.

Da werde ich es aber einfach auf einen Test ankommen lassen und das Ergebnis hier noch mal in ein paar Monaten bereitstellen.
Nach obenprofil pn email www icq
Gast 

14.10.2009, 01:04


Mach mit!

Wenn Dir die Beiträge zum Thema "Benchmark: $gentime vs. filemtime (Filecache)" gefallen haben oder Du noch Fragen hast oder Ergänzungen machen möchtest, solltest Du Dich gleich bei uns anmelden:

    » Anmelden

Registrierte Mitglieder genießen die folgenden Vorteile:
- kostenlose Mitgliedschaft
- keine Werbung
- direkter Austausch mit Gleichgesinnten
- neue Fragen stellen oder Diskussionen starten
- schnelle Hilfe bei Problemen
- Bilder und Videos hochladen
- und vieles mehr...

Verwandte Suchbegriffe

filemtime benchmark, php serialize cache, ($data["FileName"]), php file_put_contents serialize, fopen file caching, filetmtime performance, file_get_contents optimieren, php filemtime benchmark, php fopen array dateiname, unserialize(file_get_contents, performance str_replace array, php performance unserialize mysql, php refresh +kostet +besucher, php set filemtime, filemtime caching, cache benchmark database file, write array php file serialize fopen, file cache php serialize, preg_replace, php filemtime performance
Nach oben
Seite 1 von 1 [3 Beiträge]
Neues Thema eröffnenNeue Antwort erstellen

Ähnliche BeiträgeAutorAntwortenAufrufeLetzter Beitrag
3D Benchmark 
Wollte mal gucken was eure PC´s so hergeben mein pc system: Asus Crosshair ATI 2900 GT Kingstone HyperX DDR1066 2GB standart SPD mit CL 5 xD und kleiner rein hier mal nen 3Dmark03 run mit meiner neuen CPU davor AMD X2 BE 2300 ca 21000...
Seite: 2, 3, 4, 5 ]
R3DEX40142526.04.2009, 02:13
W1nter
preg_replace / preg_match Benchmark 
Danach hatte ich eigentlich gesucht und bin auf etwas vergleichbares gestoßen: http://benchmark.nophia.de/benchmarks-textverarbeitung-k-2-texte-mit-mindestens-zwei-vokalen-b-21.html Dazu hätte ich direkt einen Verbesserungsvorschlag: <?PHP ...
PHP ]
mgutt015926.02.2009, 13:25
mgutt
Benchmark: Prepared Statements in Array 
Hi, hier die Resultate: /* // version 1 // 1. run 0.14501937151 // 2. run 0.145541801453 // 3. run 0.141622686386 // fastest run 0.0934751033783 while ($field = $meta->fetch_field()) { $row[] =...
PHP ]
mgutt07609.10.2009, 18:39
mgutt
Benchmark: mysql, mysqli - Buffer, Cache und Prepared Stmt 
Hallo, ich habe mir mal die Mühe gemacht und die verschiedensten Varianten, wie man eine Abfrage gestalten könnte, in einen Benchmark gepackt und ausgewertet. Hier erstmal die umfangreichen Logs: /* // vars $id = 1111; $email =...
PHP ]
mgutt114709.10.2009, 22:59
mgutt
© 2004 - 2010 www.programmierer-forum.de | Communities | Impressum