在通过网络发送数据包之前,用于压缩数据包的最佳压缩算法是什么?数据包使用 JSON 编码。LZW 会是一个很好的选择还是有更好的选择?
7 回答
我认为有两个问题会影响你的回答:
1)在不知道程序的任何特定运行会发生什么的情况下,您能在多大程度上预测数据的组成?例如,如果您的数据包如下所示:
{
"vector": {
"latitude": 16,
"longitude": 18,
"altitude": 20
},
"vector": {
"latitude": -8,
"longitude": 13,
"altitude": -5
},
[... et cetera ...]
}
-- 那么你可能会通过创建一个硬编码的文本字符串字典来获得最好的压缩,这些字典会一直显示在你的数据中,并用适当的字典索引替换每个文本字符串的出现。(实际上,如果您的数据是这样常规的,您可能只想通过线路发送值,然后只需将一个函数写入客户端,以便在需要 JSON 对象时从这些值构造一个 JSON 对象。)
如果您无法预测将使用哪些标头,则可能需要使用 LZW 或 LZ77 或另一种查看已经经过的数据的方法,以找到它可以以特别紧凑的形式表达的数据。然而...
2)数据包是否需要彼此分开压缩?如果是这样,那么 LZW 绝对不是您想要的方法;它将没有时间将其字典构建到在单个数据包结束时会产生大量压缩结果的大小。恕我直言,在这种情况下获得真正实质性压缩的唯一机会是使用硬编码字典。
(以上所有内容的附录:正如 Michael Kohne 指出的那样,发送 JSON 意味着您可能正在发送所有文本,这意味着您未充分利用能够发送比您正在使用的字符范围更广的带宽的带宽. 但是,如何将 0-127 范围内的字符打包到包含 0-255 值的容器中的问题相当简单,我认为可以留作“读者练习”,正如他们所说。)
还有另外两种 JSON 压缩算法:CJson 和 HPack HPack 做得非常好,堪比 gzip 压缩。
嗯...如果我错了,请纠正我,但是如果您正在实施在线压缩,那么您可以控制连接的两端,对吗?在那种情况下,如果 JSON 是一个太胖的协议,为什么不选择一个不那么胖的不同有线协议呢?我的意思是,我理解使用像 JSON 这样的标准的吸引力,但是如果您担心带宽,那么您可能应该选择一个不全是文本的有线协议。
让webserver压缩,浏览器原生解压;gzip 或放气。
以下是对 JSON 数据原始压缩性的简短测试:crime-data_geojson.json 72844By(您可以在此处获取文件:https ://github.com/lsauer/Data-Hub 。该文件是随机挑选的,但不能代表平均 JSON 数据)
除了 zip,所有归档器参数都设置为 ultra
* cm/ nanozip:
> 4076/72844
[1] 0.05595519
* gzip:
> 6611/72844
[1] 0.09075559
* LZMA / 7zip
> 5864/72844
[1] 0.0805008
* Huffman / zip:
> 7382/72844
[1] 0.1013398
* ?/Arc:
> 4739/72844
[1] 0.06505683
这意味着压缩非常高且有益。JSON 数据通常具有高熵。根据维基百科
根据香农基于人体实验的估计,英文文本的熵率在每个字母 1.0 到 1.5 位之间,[1] 或低至每个字母 0.6 到 1.3 位
JSON 数据的熵通常远高于此值。(在使用 10 个大小大致相等的任意 JSON 文件的实验中,我计算出 2.36)
Gzip(deflate 算法)非常擅长压缩,尽管与所有优秀的压缩算法一样,它使用大量 cpu(在我的测试中是 json 读取/写入开销的 3-5 倍)。
我发现压缩算法往往比选择替代格式更有效。如果这是“实时”压缩,我建议研究较低级别的 Brotli 或 Zstandard 压缩器(高级压缩器占用大量 CPU - 但确实提供了非常好的压缩)。
如果您想了解所有替代方案以及我是如何得出这个结论的,可以在 Lucidchart 技术博客上找到完整的详细信息。