pyzstd.compress() 的确定性与compression.zstd的对比
我们当前正在将压缩层从pyzstd迁移到Python内置的compression.zstd模块(在Python 3.14中引入),在这一转换过程中,我们注意到一个有趣的行为差异,尚未完全解释清楚。
使用pyzstd时,以下调用在多次执行中总是产生完全相同的字节输出:
pyzstd.compress(
data=content,
zstd_dict=training_dict.as_digested_dict
)
然而,使用新的内置模块,等效的调用:
zstd.compress(
data=content,
zstd_dict=training_dict.as_digested_dict
)
……在两次连续调用相同输入时,生成的字节对象大小不同。
一个可能相关的细节是:在两次compress() 调用之间,我们通过以下方式从磁盘重新加载字典:
training_dict = zstd.ZstdDict(zst_file)
每次使用的都是完全相同的.zst文件,我们只是再次在第二次compress() 调用前执行这一行。我们不确定从同一个文件重新实例化ZstdDict是否会对最终的压缩输出产生影响,但若是一个因素,我们也想提及。
多次调用时,有时test_compress_after_reloading_dict_from_disk_produces_identical_output会失败,有时会通过。
input = {
"test_1": 1283998000000,
"test_2": 0,
"test_3": "test"
}
CONTENT = json.dumps(input).encode('utf-8')
def _load_dict(path: str) -> zstd.ZstdDict:
with open(path, "rb") as f:
return zstd.ZstdDict(f.read())
def test_compress_after_reloading_dict_from_disk_produces_identical_output():
training_dict = _load_dict(DICT_PATH)
result_1 = zstd.compress(data=CONTENT, zstd_dict=training_dict.as_digested_dict)
training_dict = _load_dict(DICT_PATH)
result_2 = zstd.compress(data=CONTENT, zstd_dict=training_dict.as_digested_dict)
assert result_1 == result_2, (
f"Reloading ZstdDict from disk changed the compressed output.\n"
f" Before reload: {len(result_1)} bytes\n"
f" After reload: {len(result_2)} bytes"
)
造成这种行为的原因可能是什么?
解决方案
从来不能保证先解码再重新压缩就能得到原始输入。对于同一数据,有很多种有效的压缩方式。对于无损压缩器而言,唯一的保证是先压缩再解压后能还原你开始时的数据。
只有在满足一系列条件时,才有可能在对同一输入进行压缩时得到相同的输出,例如使用相同的压缩代码、相同版本的代码、相同的设置,以及对该代码的相同操作。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。