PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Caching » Cache_Lite » Bug #7410

Performance enhancement with fpassthru()

Details

Request #7410Performance enhancement with fpassthru()
Submitted2006-04-17 15:26 UTC
Fromfnjordy at gmail dot com
Assignedfab
StatusSuspended
PackageCache_Lite
PHP Version5.1.2
OSLinux/Debian
Roadmaps(Not assigned)

Comments

[2006-04-17 15:26 UTC] fnjordy at gmail dot com

Description:
------------
Currently the cache contents are read into a PHP variable and output, but if you use fpassthru() PHP can send the contents of the cache, after optionally reading the hash signature, direct to the output buffer.

Some benchmarking results show fpassthru() is marginally slower for small cache sizes - presumably because of various system buffers helping out full cache reads, but for large caches, such as images, fpassthru() is signifcantly faster, a 400% speed improvement on a 2MB cache entry.

--- Lite.php?rev=1.42 2006-04-17 23:21:49.000000000 +0800
+++ /usr/share/php/Cache/Lite.php 2006-04-15 23:44:43.000000000 +0800
@@ -311,7 +311,7 @@
* @return string data of the cache (else : false)
* @access public
*/
- function get($id, $group = 'default', $doNotTestCacheValidity = false)
+ function get($id, $group = 'default', $doNotTestCacheValidity = false, $passthru = false)
{
$this->_id = $id;
$this->_group = $group;
@@ -333,11 +333,11 @@
}
if (($doNotTestCacheValidity) || (is_null($this->_refreshTime))) {
if (file_exists($this->_file)) {
- $data = $this->_read();
+ $data = $this->_read($passthru);
}
} else {
if ((file_exists($this->_file)) && (@filemtime($this->_file) > $this->_refreshTime)) {
- $data = $this->_read();
+ $data = $this->_read($passthru);
}
}
if (($data) and ($this->_memoryCaching)) {
@@ -703,7 +703,7 @@
* @return string content of the cache file (else : false or a PEAR_Error object)
* @access private
*/
- function _read()
+ function _read($passthru)
{
$fp = @fopen($this->_file, "rb");
if ($this->_fileLocking) @flock($fp, LOCK_SH);
@@ -716,7 +716,12 @@
$length = $length - 32;
}
if ($length) {
- $data = @fread($fp, $length);
+ if ($passthru) {
+ echo @fpassthru($fp);
+ $data = '';
+ } else {
+ $data = @fread($fp, $length);
+ }
} else {
$data = '';
}
--- Output.php?rev=1.4 2006-04-17 23:22:06.000000000 +0800
+++ /usr/share/php/Cache/Lite/Output.php 2006-04-15 23:40:12.000000000 +0800
@@ -43,9 +43,8 @@
*/
function start($id, $group = 'default', $doNotTestCacheValidity = false)
{
- $data = $this->get($id, $group, $doNotTestCacheValidity);
+ $data = $this->get($id, $group, $doNotTestCacheValidity, true);
if ($data !== false) {
- echo($data);
return true;
}
ob_start();

Test script:
---------------
<?php
/* vim:ts=4:sts=4:sw=2:noai:noexpandtab
*/

require_once 'Cache/Lite/Output.php';
//require_once 't/Cache_Lite-1.5.2/Lite/Output.php';

$options = array(
'cacheDir' =>'/tmp/',
'lifeTime' => 360000,
'fileLocking' => true, // local access
'automaticCleaningFactor' => 12, // 12 pictures per page, so max one clean per page
'writeControl' => false, // not using nfs
'readControl' => false, // disable hashing (slow)
'fileNameProtection' => false, // we are using sane id's
);

function test() {
global $options;

$cache = new Cache_Lite_Output($options);
if ($cache->start('test_cache')) return;
readfile('test_2359927.jpg');
// readfile('test_10844.jpg');
// readfile('test_1978.gif');
if ($cache) $cache->end();
}

$it = 1000;
error_log("start $it run\n", 3, "/tmp/phplog");
$total = 0;
for ($i = 0; $i < $it; $i++) {
error_log("start\n", 3, "/tmp/phplog");
$t = explode(' ',microtime());
$time = $t[0]+$t[1];
test();
$t = explode(' ',microtime());
$seconds = sprintf('%f',($t[0]+$t[1]-$time));
error_log("finish: $seconds seconds\n", 3, "/tmp/phplog");
$total += $seconds;
}
error_log("finish $it run: $total seconds\n", 3, "/tmp/phplog");
?>

Actual result:
--------------
1978 bytes
----------

read:

finish 1000 run: 0.177495 seconds

fpassthru:

finish 1000 run: 0.194931 seconds

10844 bytes
-----------

read:

finish 1000 run: 0.189948 seconds

fpassthru:

finish 1000 run: 0.203439 seconds

2359927 bytes
-------------

read:

finish 1000 run: 6.004331 seconds

fpassthru:

finish 1000 run: 1.546889 seconds

[2006-04-21 17:22 UTC] fab at php dot net

It's a really good test. Feel free to commit it into CVS.

[2006-05-28 12:35 UTC] fab at php dot net

Hum... I played with the patch before commiting it to CVS and I found a problem :

it's incompatible with "readControl" so it has to be an optional way of working (option "fpassthru" in constructor, big warnings in documentation...)

I don't think any more this patch is a good idea.

Any thoughts ?