尝试减少JSON大小是否值得努力?

时间:2012-06-22 17:08:24

标签: json performance http bandwidth

我从移动应用程序(最多1000个JSON对象)提交相对大量的数据,我通常会这样编码:

[{
    id: 12,
    score: 34,
    interval: 5678,
    sub: 9012
}, {
    id: ...
}, ...]

我可以通过提交一个数组数组来缩小有效负载:

[[12, 34, 5678, 9012], [...], ...]

在属性名称上保存一些空间,并在服务器上重新创建对象(因为架构已修复,或者至少它是服务器和客户端之间的契约)。

然后在POST请求中提交有效负载,最有可能通过3G连接(或可能是wifi)。

看起来我通过使用嵌套数组来节省一些带宽,但是当应用 gzip 时我不确定它是否明显,我不确定如何精确和客观地测量差。

另一方面,嵌套数组感觉不是一个好主意:它们的可读性较差,因此在调试时更难发现错误。此外,由于我们正在冲洗马桶上的可读性,我们可以简化阵列,因为每个子阵列都有固定数量的元素,服务器可以将其切片并再次重建对象。

非常感谢有关此主题的任何进一步阅读材料。

5 个答案:

答案 0 :(得分:16)

JSONH,又名hpack,https://github.com/WebReflection/JSONH做的事与你的例子非常相似:

[{
    id: 12,
    score: 34,
    interval: 5678,
    sub: 9012
}, {
    id: 98,
    score: 76,
    interval: 5432,
    sub: 1098
}, ...]

会变成:

[["id","score","interval","sub"],12,34,5678,9012,98,76,5432,1098,...]

答案 1 :(得分:12)

JSON是为了提高可读性。如果你担心空间,你可以有一个中间格式。创建一个序列化/反序列化函数,它接受一个JSON文件并创建一个压缩二进制文件,将数据存储得合理,然后在该行的另一端读取该格式。

请参阅:http://en.wikipedia.org/wiki/Json 第一句话:“JSON ...是一种基于文本的轻量级开放标准,专为人类可读的数据交换而设计。”

基本上,我的观点是人类总会看到JSON,机器会主要看到二进制文件。您可以获得两全其美:可读性和小数据传输(以少量计算为代价)。

答案 2 :(得分:9)

Gzip将使用对其首次出现的小型反向引用来替换消息的重复部分。该算法非常“愚蠢”,但对于这种重复数据,它非常棒。我认为您不会看到线上尺寸明显减少,因为您的对象“结构”只发送一次。

您可以通过压缩两个示例JSON来粗略地测试它。或者通过使用Fiddler捕获HTTP请求。它可以显示压缩和未压缩的大小。

答案 3 :(得分:7)

由于您在移动设备上使用此功能(您提及3G),您实际上可能想要关注尺寸,而不是可读性。此外,您是否经常期望阅读通过网络传输的内容?

这是对替代表格的建议。

ProtoBuf是一种选择。谷歌在内部使用它,并且有一个ProtoBuf'编译器'它可以读取.proto个文件(包含消息描述)并生成 Java / C ++ / Python 序列化器/解串器,它们使用二进制形式通过线路传输。您只需在两端使用生成的类,并忘记通过线路传输时对象的外观。还有Obj-C port maintained externally

以下是ProtoBuf网站上ProtoBuf against XML的比较(我知道XML不是你使用的,仍然是)。

最后,这是一个Python tutorial

答案 4 :(得分:6)

虽然这是一个老问题,但我想说一些话。

根据我的经验,json原始大小的差异很大,压缩后的数量很少。我更喜欢让它具有人类可读性。

在实际案例编号中:一个1,29MB的json文件,以及145KB的优化版本,压缩时,32KB和9KB。

除极端条件外,我认为这种差异可以忽略不计,可读性成本也很高。

A:

{
  "Code": "FCEB97B6",
  "Date": "\/Date(1437706800000)\/",
  "TotalQuantity": 1,
  "Items": [
    {
      "CapsulesQuantity": 0,
      "Quantity": 1,
      "CurrentItem": {
        "ItemId": "SHIELD_AXA",
        "Order": 30,
        "GroupId": "G_MODS",
        "TypeId": "T_SHIELDS",
        "Level": 0,
        "Rarity": "R4",
        "UniqueId": null,
        "Name": "AXA Shield"
      }
    }
  ],
  "FormattedDate": "2015-Jul.-24"
}

B:

{
  "fDate": "2016-Mar.-01",
  "totCaps": 9,
  "totIts": 14,
  "rDays": 1,
  "avg": "1,56",
  "cells": {
    "00": {
      "30": 1
    },
    "03": {
      "30": 1
    },
    "08": {
      "25": 1
    },
    "09": {
      "26": 3
    },
    "12": {
      "39": 1
    },
    "14": {
      "33": 1
    },
    "17": {
      "40": 3
    },
    "19": {
      "41": 2
    },
    "20": {
      "41": 1
    }
  }
}

这是两个文件的片段。