Kürzlich habe ich MessagePack gefunden , ein alternatives binäres Serialisierungsformat zu Googles Protokollpuffern und JSON, das auch beide übertrifft.
Es gibt auch das BSON- Serialisierungsformat, das von MongoDB zum Speichern von Daten verwendet wird.
Kann jemand die Unterschiede und die Nachteile von BSON gegenüber MessagePack erläutern ?
Um die Liste der performanten binären Serialisierungsformate zu vervollständigen: Es gibt auch Gobs, die der Nachfolger von Googles Protokollpuffern sein werden . Im Gegensatz zu allen anderen genannten Formaten, die nicht sprachunabhängig sind und auf Go's integrierter Reflexion beruhen, gibt es auch Gobs-Bibliotheken für zumindest eine andere Sprache als Go.
Antworten:
// Bitte beachte, dass ich Autor von MessagePack bin. Diese Antwort kann voreingenommen sein.
Format Design
Kompatibilität mit JSON
Trotz des Namens ist die Kompatibilität von BSON mit JSON im Vergleich zu MessagePack nicht so gut.
BSON hat spezielle Typen wie "ObjectId", "Min Key", "UUID" oder "MD5" (ich denke, diese Typen werden von MongoDB benötigt). Diese Typen sind nicht mit JSON kompatibel. Das bedeutet, dass einige Typinformationen verloren gehen können, wenn Sie Objekte von BSON in JSON konvertieren, aber natürlich nur, wenn sich diese speziellen Typen in der BSON-Quelle befinden. Es kann ein Nachteil sein, sowohl JSON als auch BSON in einem einzigen Dienst zu verwenden.
MessagePack kann transparent von / nach JSON konvertiert werden.
MessagePack ist kleiner als BSON
Das Format von MessagePack ist weniger ausführlich als das von BSON. Infolgedessen kann MessagePack Objekte serialisieren, die kleiner als BSON sind.
Beispielsweise wird eine einfache Zuordnung {"a": 1, "b": 2} mit MessagePack in 7 Bytes serialisiert, während BSON 19 Bytes verwendet.
BSON unterstützt die direkte Aktualisierung
Mit BSON können Sie einen Teil des gespeicherten Objekts ändern, ohne das gesamte Objekt neu zu serialisieren. Angenommen, eine Karte {"a": 1, "b": 2} ist in einer Datei gespeichert und Sie möchten den Wert von "a" von 1 auf 2000 aktualisieren.
Bei MessagePack verwendet 1 nur 1 Byte, 2000 jedoch 3 Byte. "B" muss also um 2 Bytes rückwärts verschoben werden, während "b" nicht geändert wird.
Mit BSON verwenden sowohl 1 als auch 2000 5 Bytes. Aufgrund dieser Ausführlichkeit müssen Sie "b" nicht bewegen.
MessagePack hat RPC
MessagePack, Protokollpuffer, Thrift und Avro unterstützen RPC. Aber BSON nicht.
Diese Unterschiede implizieren, dass MessagePack ursprünglich für die Netzwerkkommunikation entwickelt wurde, während BSON für Speicher konzipiert ist.
Implementierung und API-Design
MessagePack verfügt über APIs zur Typprüfung (Java, C ++ und D).
MessagePack unterstützt die statische Typisierung.
Die mit JSON oder BSON verwendete dynamische Typisierung ist nützlich für dynamische Sprachen wie Ruby, Python oder JavaScript. Aber problematisch für statische Sprachen. Sie müssen langweilige Codes für die Typprüfung schreiben.
MessagePack bietet eine API zur Typprüfung. Es konvertiert dynamisch typisierte Objekte in statisch typisierte Objekte. Hier ist ein einfaches Beispiel (C ++):
MessagePack hat IDL
MessagePack unterstützt IDL. (Die Spezifikation ist verfügbar unter: http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )
Protokollpuffer und Thrift erfordern IDL (unterstützen keine dynamische Typisierung) und bieten eine ausgereiftere IDL-Implementierung.
MessagePack verfügt über eine Streaming-API (Ruby, Python, Java, C ++, ...)
MessagePack unterstützt Streaming-Deserializer. Diese Funktion ist nützlich für die Netzwerkkommunikation. Hier ist ein Beispiel (Ruby):
quelle
Ich weiß, dass diese Frage an dieser Stelle etwas veraltet ist ... Ich denke, es ist sehr wichtig zu erwähnen, dass es davon abhängt, wie Ihre Client / Server-Umgebung aussieht.
Wenn Sie Bytes mehrmals ohne Überprüfung übergeben, z. B. mit einem Nachrichtenwarteschlangensystem oder dem Streamen von Protokolleinträgen auf die Festplatte, bevorzugen Sie möglicherweise eine Binärcodierung, um die kompakte Größe hervorzuheben. Ansonsten ist es ein Fall-zu-Fall-Problem mit verschiedenen Umgebungen.
Einige Umgebungen können eine sehr schnelle Serialisierung und Deserialisierung zu / von msgpack / protobufs haben, andere weniger. Im Allgemeinen funktioniert die binäre Serialisierung umso besser, je niedriger die Sprache / Umgebung ist. In höheren Sprachen (node.js, .Net, JVM) werden Sie häufig feststellen, dass die JSON-Serialisierung tatsächlich schneller ist. Die Frage wird dann, ob Ihr Netzwerk-Overhead mehr oder weniger eingeschränkt ist als Ihr Speicher / Ihre CPU.
In Bezug auf msgpack vs bson vs Protokollpuffer ... msgpack ist das kleinste Byte der Gruppe, wobei die Protokollpuffer ungefähr gleich sind. BSON definiert breitere native Typen als die beiden anderen und passt möglicherweise besser zu Ihrem Objektmodus, dies macht ihn jedoch ausführlicher. Protokollpuffer haben den Vorteil, dass sie für das Streaming ausgelegt sind ... was sie zu einem natürlicheren Format für ein binäres Übertragungs- / Speicherformat macht.
Persönlich würde ich mich auf die Transparenz stützen, die JSON direkt bietet, es sei denn, es besteht eindeutig ein Bedarf an weniger Verkehr. Bei HTTP mit komprimierten Daten ist der Unterschied im Netzwerk-Overhead zwischen den Formaten noch weniger problematisch.
quelle
Schnelltest zeigt, dass minimiertes JSON schneller deserialisiert wird als binäres MessagePack. In den Tests ist Article.json 550 KB minimiertes JSON, Article.mpack ist 420 KB MP-Version davon. Kann natürlich ein Implementierungsproblem sein.
MessagePack:
JSON:
Die Zeiten sind also:
So wird Platz gespart, aber schneller? Nein.
Getestete Versionen:
quelle
simplejson
2.6.2 66,7 Sekunden undmsgpack
0.2.2 nur 28,8 Sekunden dauert.Ein wesentlicher Unterschied, der noch nicht erwähnt wurde, besteht darin, dass BSON Größeninformationen in Bytes für das gesamte Dokument und weitere verschachtelte Unterdokumente enthält.
Dies hat zwei Hauptvorteile für eingeschränkte Umgebungen (z. B. eingebettet), in denen Größe und Leistung wichtig sind.
quelle
Ich habe einen schnellen Benchmark erstellt, um die Codierungs- und Decodierungsgeschwindigkeit von MessagePack mit BSON zu vergleichen. BSON ist zumindest dann schneller, wenn Sie große binäre Arrays haben:
Verwenden von C # Newtonsoft.Json und MessagePack von neuecc:
quelle
Nun, wie der Autor sagte, ist MessagePack ursprünglich für die Netzwerkkommunikation konzipiert, während BSON für die Speicherung konzipiert ist.
MessagePack ist kompakt, während BSON ausführlich ist. MessagePack soll platzsparend sein, während BSON für CURD (zeiteffizient) ausgelegt ist.
Am wichtigsten ist, dass das Typsystem (Präfix) von MessagePack der Huffman-Codierung folgt. Hier habe ich einen Huffman-Baum von MessagePack gezeichnet (klicken Sie auf den Link, um das Bild zu sehen):
quelle