是`ls -f | grep -c .` 使用 POSIX / Unix 系统(大数据)时计算目录中文件的最快方法?

Is `ls -f | grep -c .` the fastest way to count files in directory, when using POSIX / Unix system (Big Data)?

我曾经这样做 ls path-to-whatever| wc -l,直到我发现它实际上消耗了大量内存。然后我移动到 find path-to-whatever -name "*" | wc -l,它似乎消耗了大量的内存,无论你有多少文件。

然后我了解到,由于对结果进行排序,ls 的运行速度很慢且内存效率较低。通过使用ls -f | grep -c .,一个人会得到非常快的结果;唯一的问题是文件名中可能包含 "line breaks"。但是,对于大多数用例来说,这是一个非常小的问题。

这是统计文件的最快方法吗?

编辑/可能的答案:似乎在涉及大数据时,据报道某些版本的 ls、find 等挂起超过 800 万个文件(尽管需要确认)。为了成功处理非常大的文件数(我的猜测是 > 22 亿),应该使用 getdents64 系统调用而不是 getdents,这可以用大多数支持 POSIX 标准的编程语言来完成。某些文件系统可能会提供更快的非POSIX 文件计数方法。

一种方法是使用readdir 并计算条目数(在一个目录中)。下面我正在计算常规文件并使用 d_type==DT_REG,它可用于有限的操作系统和文件系统(man readdir 并参见注释),但您可以只注释掉该行并计算所有目录条目:

#include <stdio.h>
#include <dirent.h>

int main (int argc, char *argv[]) {

  struct dirent *entry;
  DIR *dirp;

  long long c;                            // 64 bit

  if(argc<=1)                             // require dir
    return 1;

  dirp = opendir (argv[1]);

  if (dirp == NULL) {                     // dir not found
    return 2;
  }

  while ((entry = readdir(dirp)) != NULL) {
    if(entry->d_type==DT_REG)
      c++;
      // printf ("%s\n", entry->d_name);  // for outputing filenames
  }
  printf ("%lli\n", c);

  closedir (dirp);
  return 0;
}

遵守 运行:

$ gcc code.c
$ ./a.out ~
254

(我需要清理我的主目录:)

编辑:

我将 1000000 个文件放入一个目录,运行 快速比较(最佳用户+系统,共 5 个):

$ time ls -f | grep -c .
1000005

real    0m1.771s
user    0m0.656s
sys     0m1.244s

$ time ls -f | wc -l
1000005

real    0m1.733s
user    0m0.520s
sys     0m1.248s

$ time ../a.out  .
1000003

real    0m0.474s
user    0m0.048s
sys     0m0.424s

编辑 2

根据评论中的要求:

$ time ./a.out testdir | wc -l
1000004

real    0m0.567s
user    0m0.124s
sys     0m0.468s