为什么以相反顺序读取压缩的 TAR 文件会慢 100 倍?

Jey*_*mon 3 python performance tar

首先,让我们生成一个压缩tar档案:

from io import BytesIO
from tarfile import TarInfo
import tarfile

with tarfile.open('foo.tgz', mode='w:gz') as archive:
    for file_name in range(1000):
        file_info = TarInfo(str(file_name))
        file_info.size = 100_000
        archive.addfile(file_info, fileobj=BytesIO(b'a' * 100_000))
Run Code Online (Sandbox Code Playgroud)

现在,如果我按自然顺序读取存档内容:

import tarfile

with tarfile.open('foo.tgz') as archive:
    for file_name in archive.getnames():
        archive.extractfile(file_name).read()
Run Code Online (Sandbox Code Playgroud)

并使用命令测量执行时间,我在 PC 上time得到的执行时间不到1 秒:

real    0m0.591s
user    0m0.560s
sys     0m0.011s
Run Code Online (Sandbox Code Playgroud)

但是如果我以相反的顺序读取存档内容:

real    0m0.591s
user    0m0.560s
sys     0m0.011s
Run Code Online (Sandbox Code Playgroud)

现在执行时间约为120 秒

real    2m3.050s
user    2m0.910s
sys     0m0.059s
Run Code Online (Sandbox Code Playgroud)

这是为什么?我的代码中有什么错误吗?或者是某些tar人的特点?它记录在某处吗?

tri*_*eee 7

文件tar是严格顺序的。你最终会读取文件的开头 1000 次,在它们之间倒带,读取第二个成员 999 次,等等。

请记住,“磁带存档”格式是在大主轴上的单向磁带卷盘是他们使用的硬件的时候设计的。拥有索引只会浪费磁带上的空间,因为您实际上必须读取磁带上您所在位置和您想要查找的位置之间的每个字节。

相比之下,现代存档格式(例如)专.zip为在适当可查找的设备上使用而设计,通常包含一个索引,可让您快速移动到可以找到特定存档成员的位置。

  • 而且文件是压缩的,这一事实使情况变得更加复杂;无法在压缩文件中查找精确的未压缩字节偏移量(并且您需要进行查找才能找到要从存档中提取的数据)。 (6认同)