是否有可能加快PHP递归文件扫描?

我一直在试图复制牛羚查找(“发现”)在PHP中,但似乎不可能得到甚至接近它的速度。 PHP的实现使用查找至少两倍的时间。 有没有用PHP这样做的更快的方法?

编辑:我添加了一个代码示例使用SPL实现 - 其性能相当于迭代方法

EDIT2:当从PHP调用发现它实际上比原生的PHP执行慢。 我想我应该满足于我有:)

// measured to 317% of gnu find's speed when run directly from a shell function list_recursive($dir) { if ($dh = opendir($dir)) { while (false !== ($entry = readdir($dh))) { if ($entry == '.' || $entry == '..') continue; $path = "$dir/$entry"; echo "$path\n"; if (is_dir($path)) list_recursive($path); } closedir($d); } } // measured to 315% of gnu find's speed when run directly from a shell function list_iterative($from) { $dirs = array($from); while (NULL !== ($dir = array_pop($dirs))) { if ($dh = opendir($dir)) { while (false !== ($entry = readdir($dh))) { if ($entry == '.' || $entry == '..') continue; $path = "$dir/$entry"; echo "$path\n"; if (is_dir($path)) $dirs[] = $path; } closedir($dh); } } } // measured to 315% of gnu find's speed when run directly from a shell function list_recursivedirectoryiterator($path) { $it = new RecursiveDirectoryIterator($path); foreach ($it as $file) { if ($file->isDot()) continue; echo $file->getPathname(); } } // measured to 390% of gnu find's speed when run directly from a shell function list_gnufind($dir) { $dir = escapeshellcmd($dir); $h = popen("/usr/bin/find $dir", "r"); while ('' != ($s = fread($h, 2048))) { echo $s; } pclose($h); }

--------------解决方案-------------

PHP只是不能提高速度为C,简单明了。

在你开始改变任何东西, 分析代码

使用类似Xdebug的(加KCacheGrind调试了一个漂亮的图表)找出缓慢部件。 如果你开始改变一味的东西,你不会得到任何地方。

我唯一​​的建议是使用SPL目录迭代器的发布了。 让内部的C代码做的工作几乎总是更快。

我不知道如果表现好,但你可以使用递归的目录迭代器,使你的代码更简单...查看RecursiveDirectoryIterator和“SplFileInfo`。

$it = new RecursiveDirectoryIterator($from);
foreach ($it as $file)
{
if ($file->isDot())
continue;

echo $file->getPathname();
}

请尝试使用

例如:RecursiveDirectoryIterator

男人:RecursiveDirectoryIterator

为什么你会希望解释PHP代码是一样快的编译的C版找? 作为唯一的慢两倍实际上是相当不错的。

关于唯一的意见,我想补充的是做一个ob_start()函数在在年底年初和ob_get_contents(),ob_end_clean()。 可能会加快速度。

你保持ň目录流,打开其中N是目录树的深度。 相反,尝试读取条目的整个目录的身价一次,然后遍历的条目。 最起码,你会最大限度地利用了台I / O缓存。

您可能要认真考虑只用GNU找到。 如果是可用的,并且安全模式没有打开,你可能会喜欢的结果就好了:

function list_recursive($dir) {
$dir=escapeshellcmd($dir);
$h = popen("/usr/bin/find $dir -type f", "r")
while ($s = fgets($h,1024)) {
echo $s;
}
pclose($h);
}

但是,有可能是一些目录中是如此之大,你不会想用这个来打扰无论是。 考虑摊销缓慢在其他方面。 你的第二次尝试通过简单地节约会话目录栈进行检查点操作(例如)。 如果你给用户的文件列表,简单地收集那么pageful状态的其余部分保存在会话中的第2页。

尝试使用scandir()读取整个目录一次,杰森·科恩曾建议。 我基于代码下面的代码来自于PHP手册评论scandir()

function scan( $dir ){
$dirs = array_diff( scandir( $dir ), Array( ".", ".." ));
$dir_array = Array();
foreach( $dirs as $d )
$dir_array[ $d ] = is_dir($dir."/".$d) ? scan( $dir."/".$d) : print $dir."/".$d."\n";
}

分类:php 时间:2015-03-14 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.549 (s). 10 q(s)