對於msgpack,官方是這樣解釋的:
messagepack 是乙個高效的二進位制序列化格式。它讓你像json一樣可以在各種語言之間交換資料。但是它比json更快、更小。小的整數會被編碼成乙個位元組,短的字串僅僅只需要比它的長度多一位元組的大小。
這裡,說了,msgpack有兩個優勢,更快(fast),更小(small).
想要了解這些優勢原因,我們當然得先知道msgpack在記憶體中是怎麼儲存的,
json資料應該已經算是很小了,沒有什麼冗餘的資料了,但msgpack是從哪些方面讓儲存占用記憶體更小的呢?
舉例:json
這個json長度為57位元組,但是為了表示這個資料結構(所有標紅色的地方就是他為了表示這個資料結構而不得不新增的),它用了23個位元組(就是那些大括號、引號、冒號之類的,他們是白白多出來的)。大家可以去 上看看json的資料標示定義。
換成messagepack,我只能給大家貼**和結果了,38位元組.
msg壓縮規則是什麼呢?
1.true、false 之類的:這些太簡單了,直接給1個位元組,(0xc2 表示true,0xc3表示false)
2.不用表示長度的:就是數字之類的,他們天然是定長的,是用乙個位元組表示後面的內容是什麼東東,比如用(0xcc 表示這後面,是個uint 8,用oxcd表示後面是個uint 16,用 0xca 表示後面的是個float 32).
3.不定長的:比如字串、陣列,型別後面加 1~4個位元組,用來存字串的長度,如果是字串長度是256以內的,只需要1個位元組,messagepack能存的最長的字串,是(2^32 -1 ) 最長的4g的字串大小。
4.ext結構:表示特定的小單元資料。
5.高階結構:map結構,就是key=>val 結構的資料,和陣列差不多,加1~4個位元組表示後面有多少個項。
這個是官方的資料表示結構文件:
總的來說,messagepack對數字、多位元組字元、陣列等都做了很多優化,減少了無用的字元,二進位制格式,也保證不用字元化帶來額外的儲存空間的增加,所以messagepack比json小是肯定的,小多少,得看你的資料。如果你用來存英文本串,那幾乎是沒有區別….
那麼,快又是從哪個方面快起來的呢?
先說說json怎麼解析吧,我們開發中一般都用cjson這個庫,cjson儲存的時候是採用鍊錶儲存的,其訪問方式很像一顆樹。每乙個節點可以有兄妹節點,通過next/prev指標來查詢,它類似雙向鍊錶;每個節點也可以有孩子節點,通過child指標來訪問,進入下一層。問題就是首先,構造這個鍊錶的時候,得乙個字元乙個字元地匹配過去吧,得判斷是不是引號、括號之類的吧…
但是messagepack 則簡單多了,直接一遍遍歷過去了,從前面的資料頭,就可以知道後面的是什麼資料,指標應該向後移動多少,比json的構建鍊錶少了很多比較的過程。
應用1:
using namespace msgpack;
using namespace std;
msgpack::sbuffer sbuf;
msgpack::packerpker(&sbuf);
// 序列化
pker.pack_map(3);
pker.pack(string("type"));
pker.pack(3);
pker.pack(string("ratio"));
pker.pack(2.15);
pker.pack(string("msg"));
pker.pack(string("hello world"));
int compresssize = sbuf.size();
// 反序列化
msgpack::v1::unpacked unpack;
msgpack::v1::unpack(&unpack, sbuf.data(), sbuf.size());
// 直接輸出結果
msgpack::object obj = unpack.get();
cout << obj << endl;
// 訪問具體鍵值對
msgpack::v2::object_kv* pkv;
msgpack::v2::object_kv* pkv_end;
msgpack::v2::object pk, pv;
if (obj.via.map.size > 0)
while (pkv < pkv_end);
}
應用2:(類的序列化)
類的序列化非常簡單,只需要類中新增一行巨集,就可以實現資料的序列化
#include #include #include #include class commandmsg ;
std::vectormy_class_vec;
commandmsg tempmsg;
tempmsg.m_mapname = "hello,dog";
tempmsg.m_map.insert(std::make_pair("aa1", 10));
tempmsg.m_map.insert(std::make_pair("aa2", 20));
my_class_vec.push_back(tempmsg);
commandmsg tempmsg2;
tempmsg2.m_mapname = "opengl";
tempmsg2.m_map.insert(std::make_pair("001", 1));
tempmsg2.m_map.insert(std::make_pair("002", 2));
tempmsg2.m_map.insert(std::make_pair("003", 3));
my_class_vec.push_back(tempmsg2);
// add some data
msgpack::v2::sbuffer buffer;
msgpack::v2::pack(buffer, my_class_vec);
msgpack::v1::unpacked msg;
msgpack::v1::unpack(&msg, buffer.data(), buffer.size());
msgpack::v1::object obj = msg.get();
std::vectormy_class_vec_r;
obj.convert(&my_class_vec_r);
for (int i = 0; i < my_class_vec.size(); i++)
}
C 資料序列化之MessagePack
對於msgpack,官方是這樣解釋的 messagepack 是乙個高效的二進位制序列化格式。它讓你像json一樣可以在各種語言之間交換資料。但是它比json更快 更小。小的整數會被編碼成乙個位元組,短的字串僅僅只需要比它的長度多一位元組的大小。這裡,說了,msgpack有兩個優勢,更快 fast ...
Django 序列化資料之單錶資料序列化
ret errors obj.errors.as data result json.dumps ret,cls jsoncustomencoder jsoncustomencoder是自定義的cls,用來轉換ret中特殊的error欄位型別 第一種 v的型別是未知的 from django.core...
C 序列化 反序列化
序列化又稱序列化,是.net執行時環境用來支援使用者定義型別的流化的機制。其目的是以某種儲存形成使自定義物件持久化,或者將這種物件從乙個地方傳輸到另乙個地方。net框架提供了兩種序列化的方式 1 是使用binaryformatter進行序列化 2 使用soapformatter進行序列化 3 使用x...