2012-06-22 7 views
15

estoy presentando relativamente gran cantidad de datos de una aplicación móvil (hasta 1000 objetos JSON), que normalmente me codificar de esta manera:¿Vale la pena intentar reducir el tamaño de JSON?

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

que podría hacer la carga útil más pequeña mediante la presentación de una matriz de matrices en su lugar:

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

para ahorrar algo de espacio en los nombres de las propiedades, y volver a crear los objetos en el servidor (como el esquema es fijo, o por lo menos es un contrato entre el servidor y el cliente).

La carga útil se presentó en una solicitud POST, probablemente a través de una conexión 3G (o podría ser wifi).

Parece que estoy ahorrando un poco de ancho de banda mediante el uso de matrices anidadas, pero no estoy seguro de que es notable cuando se aplica gzip, y no estoy seguro de cómo medir de forma precisa y objetiva la diferencia.

Por otro lado, las matrices anidadas no se sienten como una buena idea: son menos legibles y por lo tanto más difíciles de detectar errores durante la depuración. Además, como estamos descargando legibilidad por el inodoro, podríamos simplemente aplanar la matriz, ya que cada matriz hija tiene una cantidad fija de elementos, el servidor podría simplemente cortar y reconstruir los objetos nuevamente.

Cualquier otro material de lectura sobre este tema es muy apreciado.

+1

¿Qué lenguaje de programación usa en el servidor y el cliente? Por qué lo pregunto: dado que está considerando eliminar JSON, también podría usar una biblioteca que abstraiga la serialización/deserialización y todo lo que necesita importar son los objetos del lenguaje de programación nativo. – ArjunShankar

+0

@ArjunShankar Python (podría estar portado a Go en el futuro), en App Engine. –

Respuesta

12

JSONH, también conocido como hpack, https://github.com/WebReflection/JSONH hace algo muy similar a su ejemplo:

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

se convertiría en:

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

Muy agradable. Y ya hay una implementación de Python y JavaScript lista para usar. Esto parece ser mucho más fácil de conectar que ProtoBuf. –

9

JSON es para facilitar la lectura. Podría tener un formato intermedio si le preocupa el espacio. Cree una función serialize/deserialize que tome un archivo JSON y cree un binario comprimido que almacene sus datos de forma tan compacta como sea razonable, luego lea ese formato en el otro extremo de la línea.

Ver: http://en.wikipedia.org/wiki/Json Primera frase: "JSON ... es un estándar abierto basado en texto ligero diseñado para el intercambio de datos legibles por humanos."

Esencialmente, mi punto es que los humanos siempre verían el JSON, y las máquinas verían principalmente el binario. Obtienes lo mejor de ambos mundos: legibilidad y pequeña transferencia de datos (a cambio de una pequeña cantidad de computación).

+0

Gracias por su respuesta, voy a utilizar objetos JSON de fácil lectura por el momento, como sugiere, teniendo en cuenta las sugerencias de @ [usr] (http://stackoverflow.com/users/122718/usr) sobre * gzip * - hasta que tenga un fin de semana libre para imptegrar [ProtoBuf] (https://developers.google.com/protocol-buffers/) en nuestra API, como @ [ArjunShankar] (http://stackoverflow.com/users/274261/ arjunshankar) menciona. –

6

Gzip reemplazará las partes recurrentes de su mensaje con pequeñas referencias anteriores a su primera aparición. El algoritmo es bastante "tonto", pero para este tipo de datos repetitivos es genial. Creo que no verá disminuciones notables en el tamaño de cable porque la "estructura" de su objeto se envía solo una vez.

Puede probar esto aproximando dos JSON de muestra. O capturando una solicitud HTTP usando Fiddler. Puede mostrar los tamaños comprimidos y sin comprimir.

+1

GZIPed JSON vs GZIPed JSONH es _muy_ similar. – kouton

6

Dado que está utilizando esto en un dispositivo móvil (mencionas 3G), es posible que realmente te interese el tamaño, no la legibilidad. Además, ¿esperas con frecuencia leer lo que se transmite por el cable?

Esta es una sugerencia para un formulario alternativo.

ProtoBuf es una opción.Google lo usa internamente, y hay un compilador de ProtoBuf que puede leer los archivos .proto (que contienen una descripción del mensaje) y generar serializadores/deserializadores Java/C++/Python, que usan una forma binaria para la transmisión por cable. Simplemente usa las clases generadas en ambos extremos y te olvidas de cómo se ve el objeto cuando se transmite por el cable. También hay un Obj-C port maintained externally.

Aquí hay una comparación de ProtoBuf against XML, en el sitio web de ProtoBuf (sé que XML no es lo que usa, aún).

Finalmente, aquí está un Python tutorial.

4

Aunque es una vieja pregunta, me gustaría poner algunas palabras .

En mi experiencia, las grandes diferencias en el tamaño bruto json, cantidad muy poco después de la compresión. Prefiero mantenerlo legible para los humanos.

En números de casos reales: un archivo json de 1,29MB, y la versión optimizada de 145KB, cuando está comprimido, donde es de 32KB y 9KB.

Excepto en condiciones extremas, creo que este tipo de diferencias son insignificantes y el costo en legibilidad es enorme.

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

Estos son fragmentos de los dos archivos.

+0

Gracias, agente Menta, por su valiosa adición a esta pregunta;) –