MessagePack 新型序列化反序列化方案

進入在學習redis的時候,在文中看到了關於MessagePack的簡介,發現非常有意思,於是就花了點時間大致瞭解了下。

MessagePack介紹:

MessagePack is an efficient binary serialization format.It lets you exchange data among multiple languages like JSON. But it's faster and smaller.
Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves. 

MessagePack  是一個高效的二進制序列化格式。它讓你像JSON一樣可以在各種語言之間交換數據。但是它比JSON更快、更小。小的整數會被編碼成一個字節,短的字符串僅僅只需要比它的長度多一字節的大小

支持語言:

MessagePack is supported by over 50 programming languages and environments.

MessagePack和JSON壓縮後文件比較

MessagePack、protocol buffers、json的速度對比

 

MessagePack、protocol buffers、json的速度對比

這張圖片是以前MessagePack 官方網站的首頁圖片,數字對比確實很能反映問題,這裏只討論JSON和MessagePack了

爲啥會小呢?先來段json:

{“name“:”heyue“,”sex“:”\u7537“,”company“:”sina“,”age“:30} 

這個json長度爲57字節,但是爲了表示這個數據結構(所有標紅色的地方就是他爲了表示這個數據結構而不得不添加的),它用了23個字節(就是那些大括號、引號、冒號之類的,他們是白白多出來的)。

MessagePack的核心壓縮方式:

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個字節表示後面有多少個項。

這個是官方的數據表示結構文檔:https://gist.github.com/frsyuki/5432559

總的來說,MessagePack對數字、多字節字符、數組等都做了很多優化,減少了無用的字符,二進制格式,也保證不用字符化帶來額外的存儲空間的增加,所以MessagePack比JSON小是肯定的,小多少,得看你的數據。如果你用來存英文字符串,那幾乎是沒有區別….

爲啥會快呢?

先說說JSON怎麼解析吧,我們開發中一般都用cJSON這個庫,cJSON存儲的時候是採用鏈表存儲的,其訪問方式很像一顆樹。每一個節點可以有兄妹節點,通過next/prev指針來查找,它類似雙向鏈表;每個節點也可以有孩子節點,通過child指針來訪問,進入下一層。問題就是首先,構造這個鏈表的時候,得一個字符一個字符地匹配過去吧,得判斷是不是引號、括號之類的吧…

但是MessagePack 則簡單多了,直接一遍遍歷過去了,從前面的數據頭,就可以知道後面的是什麼數據,指針應該向後移動多少,比JSON的構建鏈表少了很多比較的過程

 

MessagePack主要用於結構化數據的緩存和存儲:

1.存在Memcache中,因爲它比json小,可以省下一些內存來,速度也比json快一些,頁面速度自然快一個檔次。當然,也有一種情況,我在mc中存json,然後直接出來就是頁面可用的json,都不用解析json了(當然這個在實際開發中比較少見)。

2.存在可以持久化的Key-val存儲中。

 

.NET使用

1.從GIT https://github.com/msgpack/msgpack-cli.git上下載源碼編譯生成DLL

2.示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

using System.IO;

using MsgPack.Serialization;

 

namespace MsgPack

{

class Program

{

static void Main(string[] args)

{

CreateMsgPack();

}

 

static void CreateMsgPack()

{

WriteToFile();

ReadFromFile();

 

using (var stream = new MemoryStream())

{

var serializer = MessagePackSerializer.Create<Person>();

serializer.Pack(stream, CreateIris());

stream.Position = 0;

var person = serializer.Unpack(stream);

}

}

 

static void WriteToFile()

{

var serializer = MessagePackSerializer.Create<Person>();

 

using(Stream stream = File.Open(@"C:\Users\Iris\msg.txt", FileMode.Create))

{

serializer.Pack(stream, CreateIris());

}

}

 

static void ReadFromFile()

{

var serializer = MessagePackSerializer.Create<Person>();

 

using (Stream stream = File.Open(@"C:\Users\Iris\msg.txt", FileMode.Open))

{

var iris = serializer.Unpack(stream);

}

}

 

static Person CreateIris()

{

return new Person

{

Age = 28,

Name = "Iris Classon",

FavoriteNumbers = new[] {2,3,4}

};

}

 

}

 

public class Person

{

public string Name { getset; }

public int Age { getset; }

public int[] FavoriteNumbers { getset; }

}

}

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章