27

モバイル アプリケーションから比較的大量のデータ (最大 1000 個の JSON オブジェクト) を送信していますが、通常は次のようにエンコードします。

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

代わりに配列の配列を送信することで、ペイロードを小さくすることができます。

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

プロパティ名のスペースを節約し、サーバー上でオブジェクトを再作成します (スキーマが固定されているか、少なくともサーバーとクライアント間の契約であるため)。

ペイロードは、POSTおそらく 3G 接続 (または Wi-Fi) を介してリクエストで送信されます。

ネストされた配列を使用して帯域幅を節約しているように見えますが、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 は、メッセージの繰り返し部分を、最初に出現した部分への小さな後方参照に置き換えます。アルゴリズムはかなり「ばか」ですが、この種の反復データには最適です。オブジェクトの「構造」は 1 回しか送信されないため、回線上のサイズが目立って減少することはないと思います。

2 つのサンプル JSON を圧縮することで、これを大まかにテストできます。または、Fiddler を使用して HTTP リクエストをキャプチャします。圧縮されたサイズと圧縮されていないサイズを表示できます。

于 2012-06-22T17:18:50.183 に答える
9

古い質問ですが、一言言いたいと思います。

私の経験では、json の raw サイズの大きな違いは、圧縮後はほとんどありません。私はそれを人間が読めるようにしておくことを好みます。

実際の数値: 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
    }
  }
}

これは 2 つのファイルのフラグメントです。

于 2016-04-09T02:42:42.573 に答える
8

これをモバイル デバイス (3G に言及) で使用しているため、読みやすさではなく、実際にはサイズを気にする必要があるかもしれません。さらに、ネットワーク上で送信されているものを頻繁に読み取ることを期待していますか?

これは代替フォームの提案です。

ProtoBufは 1 つのオプションです。.protoGoogle はこれを内部で使用しており、ファイル (メッセージの説明を含む) を読み取り、ネットワーク経由での送信にバイナリ形式を使用するJava/C++/Pythonシリアライザー/デシリアライザーを生成できる ProtoBuf 'コンパイラ' があります。生成されたクラスを両端で使用するだけで、ネットワーク経由で送信されたときにオブジェクトがどのように見えるかは忘れてしまいます。外部で維持される Obj-C ポートもあります。

ProtoBuf の Web サイトで、 ProtoBuf と XMLの比較を次に示します (XML はまだ使用しているものではないことはわかっています)。

最後に、Python のチュートリアルです。

于 2012-06-22T17:24:21.300 に答える