我为部分代码创建了简单的基准测试,我担心这些代码无法正常工作。我想出了非常奇怪的结果。看看这个基准:
benchmark
test file
基准代码是:
$start = microtime(true)*1000;
//code
$log=file_get_contents('test.txt').'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'."\n";
file_put_contents('test.txt', $log, LOCK_EX);
$end=microtime(true)*1000;
$time = $end-$start;
echo 'Time : '.(int)$time.'ms<br />';
$start = microtime(true)*1000;
//code
$log='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'."\n";
file_put_contents('test.txt', $log, LOCK_EX|FILE_APPEND);
$end=microtime(true)*1000;
$time = $end-$start;
echo 'Time : '.(int)$time.'ms<br />';
我注意到的是,我认为应该更快的追加选项实际上更慢。如果问题出在我的基准上那么请告诉我 谁能解释一下为什么它可能会变慢?
另外我发现当你按住F5(连续刷新)时,文本文件会被清除(:O)为什么?
修改 Ilya Bursov说,我已经改变了基准,现在在100次迭代中完成。追加操作现在似乎花费了可以忽略的时间来完成,而读取和写入将永远保持原样。但是,即使清除缓存,单次迭代仍会产生奇怪的结果。我知道这可能会受到许多事情的影响甚至误差,但是我会很感激你的回答。
答案 0 :(得分:4)
Php fopen
使用open
调用O_TRUNC
系统调用,这意味着它在以非追加模式写入之前截断文件。这种截断需要时间,并使其变慢。
截断发生后,在真实内容到达之前,您会看到空文件。
您可以在命令行中使用strace
验证这一点。
答案 1 :(得分:4)
实际上你在错误的环境中使用错误的方法测量错误的项目
以下是我的猜测为什么时间如此不同:
由于您只有一次迭代的过程,您可以拥有下一个情况:
您可以尝试稍微更改一下代码:
$start = microtime(true)*1000;
$log=file_get_contents('test.txt').'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'."\n";
file_put_contents('test.txt', $log, LOCK_EX);
clearstatcache(); // NOTE call here
$end=microtime(true)*1000;
$time = $end-$start;
echo 'Time : '.(int)$time.'ms<br />';
$start = microtime(true)*1000;
$log='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'."\n";
file_put_contents('test.txt', $log, LOCK_EX|FILE_APPEND);
clearstatcache(); // NOTE another call here
$end=microtime(true)*1000;
$time = $end-$start;
echo 'Time : '.(int)$time.'ms<br />';
现在你得到了不同的结果
<强>因此强>
测试中的时间1:从缓存中读取和写入
时间2是实际写入磁盘,可能是内存操作的一些开销
请考虑以下代码:
$appendString = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$log=file_get_contents('test.txt').$appendString."\n";
$iterations = 1000;
$start = microtime(true);
for ($i=0; $i<$iterations; $i++)
file_put_contents('test.txt', $log, LOCK_EX);
$end=microtime(true);
$time = ($end*1000 - $start*1000) / $iterations;
echo 'Time : '.$time.'ms'. "\n";
$log=$appendString."\n";
$start = microtime(true);
for ($i=0; $i<$iterations; $i++)
file_put_contents('test.txt', $log, LOCK_EX|FILE_APPEND);
$end=microtime(true);
$time = ($end*1000 - $start * 1000) / $iterations;
echo 'Time : '.$time.'ms' . "\n";
在Windows上:
Time : 0.22101293945313ms
Time : 0.039001953125ms
PHP 5.5.3 (cli) (built: Aug 20 2013 16:45:40)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Zend OPcache v7.0.3-dev, Copyright (c) 1999-2013, by Zend Technologies
在linux上:
Time : 7.6823303222656ms
Time : 0.008222900390625ms
PHP 5.4.4-14+deb7u4 (cli) (built: Aug 23 2013 14:37:41)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
这些数字看起来合理,即使有2个不同的系统,因为在第一个循环中我们必须写大字符串而在第二个循环中只有一小部分附加到它上面,我们使用迭代来计算平均结果
结论:正如预期的那样 - 追加文件比重写整个文件更快,至少因为需要的磁盘IO数量少得多