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_file
和 file_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_exists
:return false !== stat()
和is_file
:$stat = stat(); if ($stat !== false) return ($stat['mode_t'] & S_IFREG) != 0; return false
...所以is_file
应该更慢(但不多,因为stat()
仍然会主导其他简单的语言结构)...
is_file() 仅检查 arg 是否为文件。 file_exists() 检查 arg 是文件还是目录。即使两个函数中的文件/文件夹都不存在,速度也应该出来。以上是关于is_file/file_exists 性能和缓存的主要内容,如果未能解决你的问题,请参考以下文章