复制1个 1GB 文件的步骤:
- 从磁盘目录中读取文件信息
- 找到磁盘上的文件
- 找到目标上的可用空间
- 将文件的目录信息写入目的地
- 读取尽可能多的文件以适合 RAM
- 把你读过的东西写到目的地
- 关闭目标文件
- 在源上释放文件的句柄(handle)
复制 1000 个 1MB 文件的步骤:
- 从磁盘目录中读取第一个文件的信息
- 找到磁盘上的第一个文件
- 找到目标上的可用空间
- 在目的地写入第一个文件的目录信息
- 将第一个文件读入 RAM
- 把你读过的东西写到目的地
- 关闭目标上的第一个文件
- 释放源上第一个文件的句柄
- 重复以上步骤 999 次
对于1000个小文件,真正花费时间的部分不是数据大小,而是所有关于读取目录信息、在目标上分配空间、写入目录信息等等琐碎的工作。
再往下了解,1000 个文件至少需要 2000 -6000次同步到磁盘刷新轨道缓冲区的操作,而单个大文件只需要 2-6 次。
此外,即使文件的目录结构类似于 B 树,每个新创建也会导致 log2(N) 迭代,其中 N 是树中新文件的深度。
更何况,有些程序在编写的时候就没有考虑到特意优化“复制1000个文件”这种情况,他们也可能认为在现代硬件(例如 NVMe SSD)上,速度的差异可以忽略不计。
就算有些程序写得很好,它们也必须在速度和内存使用之间表现出折衷。比如在 Windows 上,通常资源管理器复制速度比某些文件管理器(例如 Far)快,但比专用程序(例如 FastCopy)慢。