【问题标题】:How to speed up sorted list of files?如何加快文件的排序列表?
【发布时间】:2013-05-05 16:18:31
【问题描述】:

我有一个需要排序的 FileSystemIterator

我在iterator_to_array(new FileSystemIterator($dir, FilesystemIterator::SKIP_DOTS)) 上使用 uaSort 函数,并带有以下排序函数:

function nameSort($a, $b) {
    if($a->isDir() === $b->isDir()){
        return strNatCaseCmp($a->getFilename(), $b->getFilename());
    }
    return $a->isDir() ? -1 : 1;
}

我在 $dir 中有 1063 个文件和目录,nameSort 被调用了 11369 次,文件列表的生成时间平均约为 6 秒。我认为额外测试项目是否是目录使 uaSort 多次调用 nameSort 但这个假设是错误的,因为当我删除带有 isDir 编号的行时调用次数增加到 11957。但运行时间下降到 0.6 秒。

看起来调用 isDir 很慢(它使列表慢了 10 倍)。如何加快速度?

【问题讨论】:

    标签: php performance sorting iterator


    【解决方案1】:

    如果调用isDir 的成本如此之高,并且您在每个路径中多次调用它,那么您可能希望缓存某个目录,然后先从缓存中检索它。这可以保护对isDir 方法的大量调用。

    【讨论】:

    • 缓存时大约需要 1 秒,不理想但相当不错。
    【解决方案2】:

    如果您只想获取单个目录的内容,可以使用 glob。

     $file = glob($path."/*", GLOB_MARK);
    

    应该已经排序并且目录可以通过拖尾 / 来识别,所以你可以 array_filter 出来

    【讨论】:

    • 我最初想使用 glob,但我更喜欢 Iterator,因为它为我提供了 SplFileInfo 及其所有简洁的方法。我将再次尝试 glob 以测试使用 is_dir 和 pathinfo 之类的函数是否不能更快。
    • 在这种情况下,如果设置了 GLOB_MARK 标志,您应该能够通过 substr($file, -1) == DIRECTORY_SEPARATOR 测试目录,应该比调用 is_dir 更便宜
    猜你喜欢
    • 2014-02-04
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 2017-10-10
    • 2021-07-08
    • 1970-01-01
    相关资源
    最近更新 更多