is_file/file_exists 性能和缓存

Posted

技术标签:

【中文标题】is_file/file_exists 性能和缓存【英文标题】:is_file/file_exists performance and cache 【发布时间】:2011-05-05 04:30:33 【问题描述】:

我做了一些测试来比较和测量这两种功能的速度。 is_file 似乎比 file_exists 快几倍(我对两者都使用了 10000 次迭代)。我想知道 php 或 OS 是否为这些功能使用了一些缓存,还是总是访问 HDD?我认为没有,但我想知道...

我使用了这个代码:

<?php
$time = microtime();
$time = explode(' ', $time);
$begintime = $time[1] + $time[0];
for($i=0;$i<10000;$i++)
    file_exists('/Applications/MAMP/htdocs/index.php');
$time = microtime();
$time = explode(" ", $time);
$endtime = $time[1] + $time[0];
$totaltime = ($endtime - $begintime);
echo 'PHP parsed this in ' .$totaltime. ' seconds.</br>';
$time = microtime();
$time = explode(" ", $time);
$begintime = $time[1] + $time[0];
for($i=0;$i<10000;$i++)
    is_file('/Applications/MAMP/htdocs/index.php');
$time = microtime();
$time = explode(" ", $time);
$endtime = $time[1] + $time[0];
$totaltime = ($endtime - $begintime);
echo 'PHP parsed this in ' .$totaltime. ' seconds.</br>';
?>

【问题讨论】:

你是否在一个紧密的循环中多次调用这个(这个效果将支配请求时间)?如果不是,除非您确定它会导致性能问题,否则我不会担心它...请记住 Premature optimization is the root of all evil... 使用语义上更好的替代方案,直到您知道这是一个问题,然后才进行优化... 确实,is_file() 比 file_exists() 快 10 倍!刚刚试了一下,确实是这样。 如果它对任何人都有帮助,我们可以添加 file_exists() 将为存在的目录和文件返回 true,其中 is_file() 只有在文件(当然存在)时才会返回 true . 【参考方案1】:

当您使用 stat()、lstat() 或任何 中列出的其他功能 受影响的函数列表(下),PHP 缓存那些功能的信息 以提供更快的回报 表现。然而,在某些 情况下,您可能需要清除 缓存的信息。例如,如果 正在检查同一文件 在一个脚本中多次, 并且该文件处于危险之中 在此期间删除或更改 脚本的操作,你可以选择 清除状态缓存。在这些 情况下,您可以使用 clearstatcache() 函数清除 PHP 缓存的关于 a 的信息 文件。

受影响的函数包括 stat()、 lstat()、file_exists()、is_writable()、 is_可读(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), 文件节点(),文件组(),文件所有者(), 文件大小(),文件类型()和 文件权限()。

【讨论】:

但是这两个函数都在那个列表中,所以这似乎并不能解释为什么一个会比另一个快得多。 您首先执行file_exists() 测试,它必须从磁盘进行实际读取并存储到statcache;然后执行is_file(),它只读取file_exists() 检查已经填充的statcache 条目,所以它(毫不奇怪)要快得多。在测试之间刷新缓存,然后您将准确地测试is_file(),因为它必须以与file_exists() 相同的方式检查磁盘并填充缓存 你的回复……太慢了。确保这是改进的;)【参考方案2】:

PHP 在统计缓存中缓存is_file()file_exists()。拨打clearstatcache()清除。

编辑: 如果有的话,两者应该花费相似的时间,因为它们都调用操作系统的stat() function,但其中一个的结果可能会被 PHP(除非你 clearstatcache())或操作系统缓存,如下 Yuliy 所述。

【讨论】:

请注意,文件操作的性能测量风险因操作系统的文件系统缓存而异 strace 显示 file_exists 调用 access("foo", F_OK)is_file 调用 stat("foo", 0x7fffe720a8a0)【参考方案3】:

is_filefile_exists 是两个不同的函数,它们做两种不同的事情; file_exists 只检查文件是否存在,is_file 判断目标是否是有效文件,并且(例如)不是目录。

它们不应该用于相同的目标,因此无法进行性能比较(恕我直言)

【讨论】:

这并不完全正确。不管功能如何设计,目标是达到预期的效果。在这种情况下,如果文件不存在,is_file() 和 file_exists() 都会返回 false。并且基准证明使用 is_file() 将使您的应用程序比使用 file_exists() 的类似应用程序更具优势。 @stillstanding:但我们在谈论什么样的优势?由于磁盘stat() 将是最慢的部分,如果两者的差异可能超过百分之一或二,我会感到惊讶。毕竟,两者都使用相同的数据,一个只是更快返回(并且两者都应该只进行一次系统调用)......至少这是我对它的理解...... @stillstanding:哪些基准测试?我认为file_exists 会稍微快一些,因为它不必检查stat structure 的mode_t 是否包含S_IFDIR。 正是@R。 Bemrose...伪代码应该是file_existsreturn false !== stat()is_file$stat = stat(); if ($stat !== false) return ($stat['mode_t'] &amp; S_IFREG) != 0; return false...所以is_file应该更慢(但不多,因为stat()仍然会主导其他简单的语言结构)... is_file() 仅检查 arg 是否为文件。 file_exists() 检查 arg 是文件还是目录。即使两个函数中的文件/文件夹都不存在,速度也应该出来。

以上是关于is_file/file_exists 性能和缓存的主要内容,如果未能解决你的问题,请参考以下文章

序列缓存和性能

Nginx缓存机制和性能优化

性能优化:关于缓存的一些思考

MySQL查询和静态缓存的性能比较

大型网站架构演进使用缓存改善网站性能

http缓存提高性能