在 CentOS(或一般 Linux)上,readdir() 慢通常是目录太大、文件系统类型、stat 调用过多、或遍历方式不对导致的。下面按「最有效 → 次有效」给你一套提速方案。
这是最有效的办法。
readdir 就会明显变慢✅ 优化方式:
data/202601/01/xxx
data/a/b/xxx
getdents64 代替 readdirreaddir() 是 glibc 封装,内部多次调用 syscall。
✅ 直接用 syscall:
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/dirent.h>
syscall(SYS_getdents64, fd, buf, size);
比 readdir() 快 30%~数倍,尤其大目录。
很多人是这样写的(很慢):
while ((entry = readdir(dir))) {
stat(entry->d_name, &st); // ❌ 每个文件一次 stat
}
✅ 优化方案:
open() + getdents64(),不进 statfstatat(AT_NO_AUTOMOUNT)statx()(CentOS 7+)不同文件系统 readdir 性能差异巨大:
| 文件系统 | 大目录 readdir |
|---|---|
| ext4 | 一般 |
| xfs | ✅ 推荐 |
| btrfs | 慢 |
| nfs | 很慢 |
✅ 建议:
mkfs.xfs /dev/sdX
如果内存小,目录缓存会被清掉。
✅ 优化:
# 提高 dentry / inode 缓存
sysctl -w vm.vfs_cache_pressure=50
readdir 在 NFS 上极慢。
✅ 方案:
rsync 再处理for f in os.listdir(path):
os.stat(path + "/" + f)
import os
for f in os.scandir(path):
pass # 不 stat
os.scandir() 比 os.listdir() 快很多。
如果目录是:
✅ 正确做法:
ls -1 | wc -l
df -T .
mount | grep "on /"
如果你愿意,可以告诉我:
我可以直接给你针对性代码或参数。