Ostatnio znalazłem MessagePack , alternatywny binarnego formatu serializacji do Google protokołu buforów i JSON , który zostawia również daleko obu.
Istnieje również format serializacji BSON używany przez MongoDB do przechowywania danych.
Czy ktoś może wyjaśnić różnice i wady / zalety BSON i MessagePack ?
Aby uzupełnić listę wydajnych formatów serializacji binarnych: Istnieją również Gobs, które będą następcą buforów protokołów Google . Jednak w przeciwieństwie do wszystkich innych wymienionych formatów, nie są one niezależne od języka i opierają się na wbudowanej refleksji w Go, istnieją również biblioteki Gobs dla przynajmniej innego języka niż Go.
Odpowiedzi:
// Pamiętaj, że jestem autorem MessagePack. Ta odpowiedź może być stronnicza.
Projekt formatu
Zgodność z JSON
Pomimo swojej nazwy, kompatybilność BSON z JSON nie jest tak dobra w porównaniu z MessagePack.
BSON ma specjalne typy, takie jak „ObjectId”, „Min key”, „UUID” lub „MD5” (myślę, że te typy są wymagane przez MongoDB). Te typy nie są zgodne z formatem JSON. Oznacza to, że niektóre informacje o typach mogą zostać utracone podczas konwersji obiektów z BSON na JSON, ale oczywiście tylko wtedy, gdy te specjalne typy znajdują się w źródle BSON. Wadą może być używanie zarówno formatu JSON, jak i BSON w jednej usłudze.
MessagePack jest przeznaczony do przezroczystej konwersji z / do formatu JSON.
MessagePack jest mniejszy niż BSON
Format MessagePack jest mniej szczegółowy niż BSON. W rezultacie MessagePack może serializować obiekty mniejsze niż BSON.
Na przykład prosta mapa {"a": 1, "b": 2} jest serializowana w 7 bajtach za pomocą MessagePack, podczas gdy BSON wykorzystuje 19 bajtów.
BSON obsługuje aktualizacje w miejscu
Dzięki BSON możesz modyfikować część przechowywanego obiektu bez ponownego serializowania całego obiektu. Załóżmy, że mapa {"a": 1, "b": 2} jest przechowywana w pliku i chcesz zaktualizować wartość "a" z 1 do 2000.
W przypadku MessagePack 1 wykorzystuje tylko 1 bajt, ale 2000 wykorzystuje 3 bajty. Zatem „b” musi zostać przesunięte w tył o 2 bajty, podczas gdy „b” nie jest modyfikowane.
W przypadku BSON zarówno 1, jak i 2000 używają 5 bajtów. Z powodu tej gadatliwości nie musisz przesuwać „b”.
MessagePack ma RPC
MessagePack, Protocol Buffers, Thrift i Avro obsługują RPC. Ale BSON tego nie robi.
Te różnice sugerują, że MessagePack został pierwotnie zaprojektowany do komunikacji sieciowej, podczas gdy BSON jest przeznaczony do magazynów.
Wdrożenie i projekt API
MessagePack ma interfejsy API do sprawdzania typów (Java, C ++ i D)
MessagePack obsługuje pisanie statyczne.
Dynamiczne pisanie używane z JSON lub BSON jest przydatne w dynamicznych językach, takich jak Ruby, Python czy JavaScript. Ale kłopotliwe dla języków statycznych. Musisz pisać nudne kody sprawdzające typ.
MessagePack zapewnia interfejs API do sprawdzania typów. Konwertuje obiekty o typie dynamicznym na obiekty o typie statycznym. Oto prosty przykład (C ++):
MessagePack ma IDL
Jest to związane z interfejsem API do sprawdzania typów, MessagePack obsługuje IDL. (specyfikacja jest dostępna pod adresem : http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )
Bufory protokołów i Thrift wymagają IDL (nie obsługują dynamicznego typowania) i zapewniają bardziej dojrzałą implementację IDL.
MessagePack ma streaming API (Ruby, Python, Java, C ++, ...)
MessagePack obsługuje deserializatory przesyłania strumieniowego. Ta funkcja jest przydatna do komunikacji sieciowej. Oto przykład (Ruby):
źródło
Wiem, że to pytanie jest trochę przestarzałe w tym momencie ... Myślę, że bardzo ważne jest, aby wspomnieć, że zależy to od tego, jak wygląda środowisko klienta / serwera.
Jeśli przekazujesz bajty wiele razy bez inspekcji, na przykład w systemie kolejek komunikatów lub przesyłaniu strumieniowym wpisów dziennika na dysk, możesz preferować kodowanie binarne, aby podkreślić kompaktowy rozmiar. W przeciwnym razie jest to problem indywidualny w różnych środowiskach.
Niektóre środowiska mogą mieć bardzo szybką serializację i deserializację do / z msgpack / protobuf, inne nie tak bardzo. Ogólnie rzecz biorąc, im bardziej niski poziom języka / środowiska, tym lepsza serializacja binarna będzie działać. W językach wyższego poziomu (node.js, .Net, JVM) często zauważysz, że serializacja JSON jest faktycznie szybsza. Powstaje zatem pytanie, czy narzut sieci jest bardziej czy mniej ograniczony niż pamięć / procesor?
W odniesieniu do buforów msgpack vs bson vs protokołów ... msgpack jest najmniejszą liczbą bajtów w grupie, bufory protokołów są mniej więcej takie same. BSON definiuje szersze typy natywne niż pozostałe dwa i może lepiej pasować do twojego trybu obiektowego, ale to czyni go bardziej szczegółowym. Bufory protokołów mają tę zaletę, że są zaprojektowane do przesyłania strumieniowego ... co sprawia, że jest to bardziej naturalny format dla binarnego formatu przesyłania / przechowywania.
Osobiście skłaniałbym się ku przejrzystości, którą JSON oferuje bezpośrednio, chyba że istnieje wyraźna potrzeba lżejszego ruchu. W przypadku protokołu HTTP z danymi spakowanymi gzip różnica w obciążeniu sieci jest jeszcze mniejszym problemem między formatami.
źródło
Szybki test pokazuje, że zminimalizowany JSON jest deserializowany szybciej niż binarny MessagePack. W testach Article.json to zminimalizowany JSON 550kb, a Article.mpack to 420kb MP-wersja. Oczywiście może to być kwestia implementacji.
MessagePack:
JSON:
A więc czasy to:
Więc miejsce jest oszczędzone, ale szybciej? Nie.
Testowane wersje:
źródło
simplejson
2.6.2 zajmuje 66,7 sekundy, amsgpack
0.2.2 zajmuje tylko 28,8.Kluczową różnicą, o której jeszcze nie wspomniano, jest to, że BSON zawiera informacje o rozmiarze w bajtach dla całego dokumentu i dalszych zagnieżdżonych dokumentów podrzędnych.
Ma to dwie główne zalety w przypadku środowisk o ograniczonym dostępie (np. Wbudowanych), w których ważny jest rozmiar i wydajność.
źródło
Zrobiłem szybki test porównawczy, aby porównać szybkość kodowania i dekodowania MessagePack vs BSON. BSON jest szybszy, przynajmniej jeśli masz duże tablice binarne:
Korzystanie z C # Newtonsoft.Json i MessagePack firmy neuecc:
źródło
Cóż , jak powiedział autor , MessagePack jest pierwotnie przeznaczony do komunikacji sieciowej, podczas gdy BSON jest przeznaczony do magazynów.
MessagePack jest kompaktowy, podczas gdy BSON jest gadatliwy. MessagePack ma oszczędzać miejsce, podczas gdy BSON jest przeznaczony dla CURD (oszczędność czasu).
Co najważniejsze, system typów MessagePack (prefiks) jest zgodny z kodowaniem Huffmana, tutaj narysowałem drzewo Huffmana MessagePack (kliknij link, aby zobaczyć obraz) :
źródło