27

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

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

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

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

在属性名称上节省一些空间,并在服务器上重新创建对象(因为模式是固定的,或者至少它是服务器和客户端之间的合同)。

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

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

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

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

4

5 回答 5

19

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,...]
于 2013-01-03T00:38:19.200 回答
14

JSON 旨在提高可读性。如果您担心空间,您可以使用中间格式。创建一个序列化/反序列化函数,该函数接受一个 JSON 文件并创建一个压缩二进制文件,尽可能紧凑地存储您的数据,然后在该行的另一端读取该格式。

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

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

于 2012-06-22T17:13:12.267 回答
11

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

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

于 2012-06-22T17:18:50.183 回答
9

虽然是个老问题,但我还是想说几句。

根据我的经验,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"
}

乙:

{
  "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
    }
  }
}

这是两个文件的片段。

于 2016-04-09T02:42:42.573 回答
8

由于您在移动设备上使用它(您提到了 3G),您可能实际上想要关心大小,而不是可读性。此外,您是否经常希望阅读通过网络传输的内容?

这是对替代形式的建议。

ProtoBuf是一种选择。Google 在内部使用它,并且有一个 ProtoBuf “编译器”,它可以读取.proto文件(包含消息描述)并生成Java/C++/Python序列化器/反序列化器,它们使用二进制形式通过网络传输。您只需在两端使用生成的类,而忘记通过网络传输时对象的外观。还有一个外部维护的 Obj-C 端口

这是ProtoBuf 与 XML的比较,在 ProtoBuf 网站上(我知道 XML 不是你使用的,仍然)。

最后,这是一个Python 教程

于 2012-06-22T17:24:21.300 回答