【问题标题】:Why is in-place edditing of a file slower than making a new file?为什么就地编辑文件比创建新文件慢?
【发布时间】:2018-06-14 15:46:42
【问题描述】:

正如您在this 答案中看到的那样。就地编辑文本文件似乎比创建新文件、删除旧文件以及从另一个文件系统移动临时文件并重命名它需要更多时间。更不用说在同一个文件系统中创建一个新文件并重命名它。我想知道这背后的原因是什么?

【问题讨论】:

    标签: performance io filesystems inplace-editing


    【解决方案1】:

    虽然 tgwtdt 的回答可能会提供一些很好的见解,但它并不能解释一切。下面是一个 140MB 文件的反例:

    $ time sed 's/a/b/g' data > newfile
    real    0m2.612s
    
    $ time sed -i -- 's/a/b/g' data 
    real    0m9.906s
    

    您可能会问,为什么这是一个反例。因为我用b替换了a,这意味着替换文本的长度相同。因此,无需移动数据,但仍需要大约四倍的时间。

    虽然 tgwtdt 很好地解释了为什么到位通常需要更长的时间,但对于一般情况,这是一个无法 100% 回答的问题,因为它取决于实现。

    【讨论】:

    • @yukashimahuksay 我可以,但这毫无意义。它不起作用。
    • 只是一个空文件
    • 大声笑,好吧,但请解释一下目的。
    • 时间几乎无法测量。 0.064s
    • @yukashimahuksay 这是我用来创建文件的内容:rm data.txt; for i in $(seq 10000000); do echo 1234443$i,asdfgdf >> data.txt; done 使用它并做所有你想做的实验。 :)
    【解决方案2】:

    因为当您就地编辑文件时,您打开同一个文件进行写入和读取。但是当你使用另一个文件时。您只能从一个文件读取并写入另一个文件。 当您打开一个文件进行读取时,它的内容会从磁盘移动到内存。然后,当您要编辑文件时,您可以更改磁盘中文件的内容,以便更新内存中的内容以防止数据不一致。但是当你使用一个新文件时。您不必更新内存中第一个文件的内容。您只需读取整个文件一次并写入另一个文件一次。并且不要更新任何东西。删除文件也需要非常短的时间,因为您只需将其从文件系统中删除,并且不会将任何位写入磁盘中文件的位置。重命名也是如此。移动也可以非常快,具体取决于文件系统,但很可能不如删除和重命名快。

    还有一个更重要的原因。

    当您从第一行的开头删除数字时,所有其他字符都必须向后移动一点。然后,当您再次从第二行中删除数字时,该点之后的所有字符都必须向后移动,因为字符必须是连续的。如果您只想更改一些字符,那么就地编辑会更快一些。但是,由于您在每次删除时都更改了文件的长度,因此所有其他字符都必须移动,这需要花费大量时间。它不完全是这样,并且根据您的操作系统和文件系统的实现,它要复杂得多,但这就是它背后的想法。这就像数组操作。当您从数组中删除单个元素时,您必须移动数组的所有其他元素。因为它是一个数组。相反,如果要从链表中删除一个元素,则不需要移动其他元素,但文件的实现类似于数组,就是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-11
      • 2015-11-27
      • 2011-07-29
      相关资源
      最近更新 更多