m4n*_*n07 5 c c++ linux embedded-linux
我有一个运行linux的目标板,目录中大约有500万多个文件。(此目录没有任何子目录)如果我执行此程序,则需要几分钟来获取总空间信息。有没有更快的方法可以做到这一点?谢谢
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/stat.h>
#include <errno.h>
void calcSpace(char *path, long long int *totalSpace)
{
DIR *dir; /* dir structure we are reading */
struct dirent *ent; /* directory entry currently being processed */
char absPath[200];
struct stat statbuf; /* buffer for stat()*/
long long int fileCount=0;
fprintf(stderr, "Opening dir %s\n", path);
dir = opendir(path);
if(NULL == dir) {
perror(path);
return;
}
while((ent = readdir(dir)))
{
fileCount++;
sprintf(absPath, "%s/%s", path, ent->d_name);
if(stat(absPath, &statbuf)) {
perror(absPath);
return;
}
*totalSpace= (*totalSpace) + statbuf.st_size;
}
fprintf(stderr, "Closing dir %s\n", path);
printf("fileCount=%lld.\n", fileCount);
closedir(dir);
}
int main(int argc, char *argv[])
{
char *dir;
long long int totalSpace=0;
if(argc > 1)
dir = argv[1];
else
dir = ".";
calcSpace(dir, &totalSpace);
printf("totalSpace=%lld\n", totalSpace);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 1
正如评论中所述,主要成本似乎是stat和 的调用readdir。
优化readdir通话
readdir我们可以使用系统调用来节省一些严重的成本getdents(2)。此系统调用类似于“readdir”,但您可以使用它来读取每个系统调用中的多个目录条目 - 大大减少了调用的开销readdir为每个条目调用系统调用的开销。
man可以在我链接到的页面中找到代码示例。getdents需要注意的重要一点是,您可能应该使用(参数 - 在示例中为 1024)调整一次读取的条目数量count,以找到您的配置和机器的最佳位置(此步骤可能会给出您想要的性能改进readdir)。
优化stat通话
建议使用该fstatat(2)函数而不是stat您使用的常规函数(两者的相关手册页)。这是因为第一个参数fstatat(2)是dirfd- 您所声明的文件所在目录的文件描述符。
这意味着您可以打开目录的文件描述符一次(使用open(2)),然后所有fstatat调用都将使用此完成dirfd。这将优化内核中的声明过程(因为不应再为每个系统调用解析整个路径和目录本身的引用stat),并且可能会使您的代码更简单且更快一点(因为路径串联不会不再需要)。