在Mac/Linux下删除一个很大很深的文件夹似乎比Windows要快,造成这种差别的原因是什么?

by 北极

影响删除文件的速度有几个因素:

1. 软件层面计算问题:比如Windows资源管理器会在删除前先统计有多少文件要删除,生成一个需要删除文件的list,再计算删除需要的时间,这个过程相当于先要遍历整个被删除的文件树,所以Windows慢。要解决这个问题,用命令行删除会明显更快(rd /s /q)。

2. 回填数据的问题:轮子哥的回答里说了,这个我个人不太了解,有回填数据肯定会影响删除性能。Linux默认肯定是不回填的,但我觉得Windows上应该有配置开关可以控制,而且似乎Win7里NTFS数据恢复工具也是可以正常工作的,是不是默认关闭的?

3. 延迟写入的问题:这个是造成二者性能明显差异的关键。延迟写入(Allocate-on-flush)可以让文件系统不实时的更新磁盘上的信息,也就是说,你即使删除了十个文件,这十个文件可能还在磁盘上原封不动的放着,然后等后续操作系统或者磁盘空闲的情况下一起删除。ext4、XFS、ZFS、Btrfs、HFS+都支持延迟写入,NTFS目前并不支持延迟写入。

需要注意的是,这里的延迟写入不仅仅表现在文件系统方面,也表现在操作系统缓存的策略方面,Windows在Vista之前缓存策略相当保守,即使到现在,Windows对系统缓存的使用率并不算高,而Linux则是尽量地占用更多的内存。

延迟写入的好处就是性能好,比如删除十万个文件,没有延迟写入的情况下可能要提交几十万次写磁盘请求(更新日志、更新父节点、更新bitmap、删除自身等),但如果有延迟写入,大量的写磁盘请求可以合并成同一个操作,减少I/O次数(写合并)。对于一般的设备来说IOPS(每秒处理IO次数)都是有瓶颈的。

但延迟写入的坏处也很明显,意外掉电可能会丢数据,数据回滚的内容无法预期。明明已经提示文件被删除了,突然计算机掉电了,重启一下居然文件还没删掉。

有一个简单的实验可以观察Linux的延迟写入:插入一个U盘,在U盘上新建一个文件,写入几个字节的数据(不能太多),写完以后马上拔出U盘,插到另外一台电脑上看,U盘里刚新建的小文件并不存在(对于Linux来说C语言里的fclose并不一定会触发写文件到物理设备)。

所以,操作系统删除文件快慢,本质上是看文件系统的策略,而操作系统是否支持这种策略取决于厂商的态度,有人更注重数据安全,有人更注重性能,可靠性和性能不可能同时获得,这也就造成了Windows和Linux/Mac的差异。

再补充点个人理解上的私货:

Linux因为有一切皆文件的思想存在,文件系统的地位是非常高的,VFS是操作系统的核心之一,所以文件系统的性能是Linux特别关注。而Windows里,文件系统只是作为一个驱动而存在,其核心是CC-Manager等组件,,NTFS也不在内核文件NTOSKRNL里,所以二者的地位是不一样的。性能上有差异也是可以理解的。

再补充一点:

Windows删除的过程,强制刷新缓存的动作很多,这是Windows文件系统设计思路的问题。Windows无法删除一个正在打开的文件,这就要求删除之前关闭文件对应的缓存、释放所有的锁,这一步在Linux上是没有的。Linux可以删除任何打开的文件

因为Windows缓存策略和Linux不同,包括锁的策略也不同,所以二者性能上会有很大的差异。至于为什么要设计成这样,这要问MS和Linus了。

Windows的FAT驱动是可以看到源码的,在WDK里就有,FatSetRenameInfo函数就是负责执行删除动作的。

作者:北极
链接:https://www.zhihu.com/question/22404752/answer/78931816
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

留下评论

电子邮件地址不会被公开。 必填项已用*标注