【问题标题】:Compressed JSON is bigger than non-compressed version压缩的 JSON 比未压缩的版本大
【发布时间】:2019-07-12 14:07:18
【问题描述】:

我会尽量澄清我的问题。

myJSON 是一个简单的 JSON 字符串。 len(myJSON) = 78

e 是json.Marshal(myJSON)

据我了解,e 现在是[]byte

然后我像这样 gzip e:

var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
gz.Write(e)
gz.Close()

buf.Len() = 96

那么...为什么我的压缩缓冲区比原始的非压缩字符串大?

编辑:当有人试图了解为什么会发生某事时,投反对票的巨魔很可笑。我想我应该只是盲目地接受它而不是问。

【问题讨论】:

  • 因为原来只有78个字节。 Gzip 不会神奇地使字节变小。它需要足够大的语料库来找到足够多的重复字节序列以使压缩有效。
  • 供参考,gzip 使用 DEFLATE 算法:en.wikipedia.org/wiki/DEFLATE
  • @Adrian。谢谢。对我来说,这似乎是一个问题。很多人盲目地在他们的 json 上使用 gzip,认为它变得更小了。我想可以肯定的是,您必须在代码中进行这样的练习才能确定 gzip 是否值得。
  • 任何工具都会被那些在没有完全理解的情况下选择使用它的人误用。 Gzip 对小型有效负载和任何没有大量重复字节序列的有效负载(例如,任何已经压缩的东西,如 JPEG 或 MP3,或加密数据)无效。一般 gzip 开始对 500~1000 字节标记左右的纯文本生效,并且在更大的有效负载下更有效。

标签: json go gzip


【解决方案1】:

设计一种无损压缩算法来减小每个输入文档的大小在物理上是不可能的。

作为一个思想实验,假设存在这样的压缩器,并且可以将任何文档压缩至少一位。

现在假设我生成了最多 N 位长的每个文档。即 1 个长度为 0 的文档、长度为 1 的 2 个文档、长度为 2 的 4 个文档等。此序列的文档总数为 2^(N+1)-1

如果我们通过压缩器运行所有文档,则压缩版本的长度最多为 N-1 位。这意味着最多可以有2^N-1 压缩文档,这比我们开始时要少。要么是压缩系统是有损的(在这种情况下,解压不一定会给我们原始文档),要么是某些文档在压缩时必须变大。

【讨论】:

  • 老故事是这样的:如果你可以创建一个无损算法,可以将每个输入减少至少 1 位,重复足够多次(在上一次运行的输出上),你可以将整个互联网压缩成一点点……
【解决方案2】:

gzip 将添加一个 header 并对原始数据进行一些更改。对于这种情况,原始数据确实很小,不能保证压缩后的数据会小于原始数据。

因此,如果您的程序将不断处理这样的小数据。压缩数据使用压缩库可能不是一个好主意。有时我们将数据序列化为二进制流,以应对数据一直很小的情况。

去 gzip 包参考:

gzip包实现gzip格式压缩的读写 RFC 1952 中指定的文件。

RFC1952

gzip 格式和标头:

http://www.onicos.com/staff/iz/formats/gzip.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多