在 Debian(以及大多数 Linux 发行版)上,readdir 读取目录“慢”,通常不是 readdir 本身的问题,而是文件系统、目录结构、缓存状态或应用使用方式导致的。下面从常见原因到排查方法系统说明。
readdir() 是 glibc 对 getdents() / getdents64() 系统调用的封装例如:
ls /var/spool/mail/
ls /data/images/
如果目录中有 几万~几百万个文件:
readdir 本身不慢stat()、排序、过滤)✅ 表现:
ls 很慢find 很快(不排序、不 stat)✅ 验证:
ls -U | wc -l # 不排序
ls | wc -l # 排序
很多程序会这样写:
while ((entry = readdir(dir))) {
stat(entry->d_name, &st);
}
问题:
readdir 只返回文件名stat 需要访问 inode✅ 表现:
✅ 检查:
strace your_program 2>&1 | grep stat
| 文件系统 | readdir 性能 |
|---|---|
| ext4 | 好 |
| xfs | 非常好(大目录) |
| btrfs | 差(大目录) |
| nfs | 容易慢 |
| fuse | 很慢 |
✅ 查看:
df -T
如果是 NFS:
readdir 会触发 网络往返readdirplus(带 stat)✅ 表现:
✅ 常见优化:
mount -o nocto,noatime,nodiratime
第一次访问目录:
第二次访问:
✅ 验证:
time ls /bigdir
time ls /bigdir
✅ 检查:
dmesg | grep ext4
✅ 修复:
umount /partition
fsck.ext4 /dev/sdX
strace -c ls /bigdir
关注:
getdents64statlstat如果 stat 占比高 → 不是 readdir 的问题
// 只 readdir,不 stat
while ((ent = readdir(dir))) {
puts(ent->d_name);
}
✅ 如果这样快,说明是 stat / 排序 / 应用逻辑 的问题
readdir 就够了❌ 不推荐:
/data/images/1000000_files
✅ 推荐:
/data/images/a/1/2/3.jpg
Debian 上 readdir 慢,99% 不是 readdir 本身慢,而是:
- 目录太大
- 每次 readdir 后 stat
- 文件系统或 NFS
- 缓存未命中
如果你愿意,可以告诉我:
我可以帮你精确定位是哪一步慢。