json - gzip json 与高效二进制序列化的性能

标签 json optimization serialization gzip cost-management

JSON 和 Gzip 是序列化数据的简单方法。这些在编程语言中被广泛实现。此外,这种表示可以跨系统移植(是吗?)。

我的问题是,与非常有效的二进制序列化方法相比,json+gzip 是否足够好(成本低于 2 倍)?我在序列化各种数据的同时寻找空间和时间成本。

最佳答案

对于数字和对象,使用 json+gzip 序列化比 rawbytes+gzip 使用多 25% 的空间。对于有限精度的数字(4 位有效数字),序列化大小是相同的。看来对于小规模的应用来说,使用json+gzip在数据量上已经足够了。即使在发送记录数组时,每条记录都完整地说明字段和值(在 JavaScript 中存储数据的常用方法)也是如此。

以下实验的来源:https://github.com/csiz/gzip-json-performance

数字

我选择了一百万个浮点(64 位)数字。我假设这些数字来自一些自然来源,所以我使用指数分布来生成它们,然后将它们四舍五入为 4 位有效数字。因为 JSON 写下了整个表示,我认为存储大数字可能会产生更大的成本(例如,存储 123456.000000,与 0.123456),所以我检查了这两种情况。我还检查了尚未四舍五入的序列号。

序列化小数字时,压缩 json 使用的大小比压缩二进制大 9%(大约 1.0 的数量级,因此只需记下几位数字):

json 3.29mb json/raw 43%
binary 3.03mb binary/raw 40%
json/binary 1.09

序列化大数字时,压缩 json 使用的大小比压缩二进制小 17%(大约 1000000 的数量级,要记下更多数字):
json 2.58mb json/raw 34%
binary 3.10mb binary/raw 41%
json/binary 0.83

序列化全精度 double 时,压缩 json 使用的大小比压缩二进制大 22%:
json 8.90mb json/raw 117%
binary 7.27mb binary/raw 95%
json/binary 1.22

对象

对于对象,我在 JSON 中以通常的懒惰方式序列化它们。每个对象都存储为带有字段名称和值的完整记录。 “选择”枚举已经完全阐明了它的值(value)。
[
  {
    "small number": 0.1234,
    "large number": 1234000,
    "choice": "two"
  },
  ...
]

而为了有效的二进制表示,我对对象进行了矢量化。我存储对象的数量,然后是小数字的连续向量,然后是选择枚举的连续向量。在这种情况下,我假设枚举值是已知且固定的,因此我将索引存储到该枚举中。
n = 1e6
small number = binary([0.1234, ...])
large number = binary([1234000, ...])
choice = binary([2, ...]) # indexes to the enum ["zero", "one", ..., "four"]

存储对象时,压缩 json 使用的大小比压缩二进制大 27%:
json 8.36mb json/raw 44%
binary 6.59mb binary/raw 35%
json/binary 1.27

关于json - gzip json 与高效二进制序列化的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35845850/

相关文章:

c++ - 删除字符串中具有相同值的任何相邻字母的 “pair”

c++ - 如何通过SAT和优化解决顶点覆盖问题?

php - 将 php session 变量序列化为 json 格式

javascript - 获取数组字段名称

c++强制编译器选择退出某些代码

.net - 删除根节点下的所有命名空间

java - 以最少的代码编写将 Java 对象序列化为 Map(并解析回来)的最快方法是什么?

python - 在 Python(噩梦般的 JSON 结构)中展平未知深度的字典列表(等)

json - Swift json 时间值到本地时区

serialization - Kotlin 序列化 : "Unresolved reference: serializer"