alternatives alternative serialization deserialization bson msgpack messagepack

serialization - alternative - Serialización de entidad performante: BSON vs MessagePack(vs JSON)



json alternatives (3)

Recientemente encontré MessagePack , un formato de serialización binario alternativo para los Buffers de Protocolo de Google y JSON que también supera a ambos.

También está el formato de serialización BSON que MongoDB utiliza para almacenar datos.

¿Puede alguien explicar las diferencias y las desventajas de BSON frente a MessagePack ?

Solo para completar la lista de formatos de serialización binarios en ejecución: también hay Gobs que serán los sucesores de los Búferes de Protocolo de Google . Sin embargo, a diferencia de todos los otros formatos mencionados, no son independientes del idioma y se basan en la reflexión incorporada de Go, también hay bibliotecas Gobs para al menos en otro idioma que Go.


// Tenga en cuenta que soy autor de MessagePack. Esta respuesta puede ser parcial.

Formato de diseño

  1. Compatibilidad con JSON

    A pesar de su nombre, la compatibilidad de BSON con JSON no es tan buena en comparación con MessagePack.

    BSON tiene tipos especiales como "Id. De objeto", "Tecla min", "UUID" o "MD5" (creo que estos tipos son requeridos por MongoDB). Estos tipos no son compatibles con JSON. Significa que se pierde cierta información de tipo al convertir objetos de BSON a JSON. Puede ser una desventaja utilizar JSON y BSON en un solo servicio.

    MessagePack está diseñado para convertirse de forma transparente de / a JSON.

  2. MessagePack es más pequeño que BSON

    El formato de MessagePack es menos detallado que BSON. Como resultado, MessagePack puede serializar objetos más pequeños que BSON.

    Por ejemplo, un mapa simple {"a": 1, "b": 2} se serializa en 7 bytes con MessagePack, mientras que BSON usa 19 bytes.

  3. BSON admite actualizaciones en el lugar

    Con BSON, puede modificar parte del objeto almacenado sin volver a serializar todo el objeto. Supongamos que un mapa {"a": 1, "b": 2} se almacena en un archivo y desea actualizar el valor de "a" de 1 a 2000.

    Con MessagePack, 1 usa solo 1 byte pero 2000 usa 3 bytes. Entonces, "b" debe retroceder 2 bytes, mientras que "b" no se modifica.

    Con BSON, tanto 1 como 2000 usan 5 bytes. Debido a esta verbosidad, no tiene que mover "b".

  4. MessagePack tiene RPC

    MessagePack, Protocol Buffers, Thrift y Avro soportan RPC. Pero BSON no lo hace.

Estas diferencias implican que MessagePack está diseñado originalmente para la comunicación de red, mientras que BSON está diseñado para almacenamientos.

Implementación y diseño de API

  1. MessagePack tiene API de comprobación de tipos (Java, C ++ y D)

    MessagePack admite tipado estático.

    La tipificación dinámica utilizada con JSON o BSON es útil para lenguajes dinámicos como Ruby, Python o JavaScript. Pero problemático para los lenguajes estáticos. Debe escribir códigos aburridos de verificación de tipos.

    MessagePack proporciona API de comprobación de tipos. Convierte objetos de tipo dinámico en objetos de tipo estático. Aquí hay un ejemplo simple (C ++):

    #include <msgpack.hpp> class myclass { private: std::string str; std::vector<int> vec; public: // This macro enables this class to be serialized/deserialized MSGPACK_DEFINE(str, vec); }; int main(void) { // serialize myclass m1 = ...; msgpack::sbuffer buffer; msgpack::pack(&buffer, m1); // deserialize msgpack::unpacked result; msgpack::unpack(&result, buffer.data(), buffer.size()); // you get dynamically-typed object msgpack::object obj = result.get(); // convert it to statically-typed object myclass m2 = obj.as<myclass>(); }

  2. MessagePack tiene IDL

    Está relacionado con la API de verificación de tipo, MessagePack es compatible con IDL. (la especificación está disponible en: http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )

    Los Buffers de protocolo y Thrift requieren IDL (no son compatibles con el tipado dinámico) y proporcionan una implementación de IDL más madura.

  3. MessagePack tiene una API de transmisión (Ruby, Python, Java, C ++, ...)

    MessagePack admite deserializadores de transmisión. Esta característica es útil para la comunicación de red. Aquí hay un ejemplo (Ruby):

    require ''msgpack'' # write objects to stdout $stdout.write [1,2,3].to_msgpack $stdout.write [1,2,3].to_msgpack # read objects from stdin using streaming deserializer unpacker = MessagePack::Unpacker.new($stdin) # use iterator unpacker.each {|obj| p obj }


La prueba rápida muestra que el JSON minimizado se deserializa más rápido que el MessagePack binario. En las pruebas Article.json es 550 kb minificado JSON, Article.mpack es 420kb MP-versión de la misma. Puede ser un problema de implementación, por supuesto.

MessagePack:

//test_mp.js var msg = require(''msgpack''); var fs = require(''fs''); var article = fs.readFileSync(''Article.mpack''); for (var i = 0; i < 10000; i++) { msg.unpack(article); }

JSON:

// test_json.js var msg = require(''msgpack''); var fs = require(''fs''); var article = fs.readFileSync(''Article.json'', ''utf-8''); for (var i = 0; i < 10000; i++) { JSON.parse(article); }

Así que los tiempos son:

Anarki:Downloads oleksii$ time node test_mp.js real 2m45.042s user 2m44.662s sys 0m2.034s Anarki:Downloads oleksii$ time node test_json.js real 2m15.497s user 2m15.458s sys 0m0.824s

Entonces el espacio se guarda, ¿pero más rápido? No.

Versiones probadas:

Anarki:Downloads oleksii$ node --version v0.8.12 Anarki:Downloads oleksii$ npm list msgpack /Users/oleksii └── [email protected]


Sé que esta pregunta está un poco anticuada en este punto ... Creo que es muy importante mencionar que depende de cómo se vea el entorno de su cliente / servidor.

Si transfiere bytes varias veces sin inspección, como con un sistema de cola de mensajes o entradas de registro de transmisión en disco, entonces puede preferir una codificación binaria para enfatizar el tamaño compacto. De lo contrario, es un problema caso por caso con diferentes entornos.

Algunos entornos pueden tener serialización y deserialización muy rápidas a / de msgpack / protobuf, otros no tanto. En general, cuanto más bajo sea el nivel de idioma / entorno, mejor será la serialización binaria. En lenguajes de nivel superior (node.js, .Net, JVM), a menudo verá que la serialización JSON es realmente más rápida. La pregunta entonces es ¿su sobrecarga de red está más o menos limitada que su memoria / CPU?

Con respecto a los búferes de msgpack vs bson vs protocol ... msgpack es el mínimo de bytes del grupo, los búferes de protocolo son más o menos lo mismo. BSON define tipos nativos más amplios que los otros dos, y puede ser una mejor coincidencia con su modo de objeto, pero esto lo hace más detallado. Los búferes de protocolo tienen la ventaja de estar diseñados para transmitir ... lo que lo convierte en un formato más natural para un formato de transferencia / almacenamiento binario.

Personalmente, me inclino por la transparencia que ofrece JSON directamente, a menos que exista una clara necesidad de un tráfico más ligero. A través de HTTP con datos comprimidos, la diferencia en la sobrecarga de la red es un problema aún menor entre los formatos.