You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何反向读取压缩TAR文件速度慢100倍?

tar.gz反向读取耗时暴增的原因解析

首先,生成一个压缩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))

按自然顺序读取归档内容:

import tarfile

with tarfile.open('foo.tgz') as archive:
    for file_name in archive.getnames():
        archive.extractfile(file_name).read()

使用time命令测量执行时间,测试环境耗时不到1秒:

real    0m0.591s
user    0m0.560s
sys     0m0.011s

但按反向顺序读取归档内容时:

import tarfile

with tarfile.open('foo.tgz') as archive:
    for file_name in reversed(archive.getnames()):
        archive.extractfile(file_name).read()

执行时间暴增至约120秒:

real    2m3.050s
user    2m0.910s
sys     0m0.059s

核心原因

这不是代码bug,是gzip压缩格式的特性导致的:

  1. gzip的流式压缩限制:gzip是流式压缩算法,没有内置索引支持快速定位压缩流中的任意位置。要读取压缩流靠后的内容,必须从开头开始解压缩,直到找到目标位置。
  2. tar归档的存储逻辑:tar是将文件依次拼接的归档格式,结合gzip后整个归档是连续的压缩流。调用archive.getnames()时,tarfile模块已经遍历完整个归档(从开头解压缩到末尾),文件指针停在归档末尾。
  3. 反向读取的重复解压缩:反向读取时,每次调用extractfile(file_name),tarfile都需要从归档开头重新解压缩,一路定位到目标文件位置。1000个文件就意味着要重复1000次从头解压缩的过程,总耗时自然剧增。
  4. 正向读取的高效性:正向读取时,文件指针按顺序移动,解压缩过程连续,只需一次完整解压缩就能读取所有文件,因此效率极高。

相关文档说明

Python的tarfile模块文档明确提到,对于gz这类压缩格式的tar归档,随机访问效率极低,因为压缩格式不支持随机定位。如果需要高效随机访问,建议使用未压缩的tar归档,或改用内置文件位置索引的zip格式。

内容的提问来源于stack exchange,提问作者Jeyekomon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:47:42