<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      MessagePack簡析

      一、MessagePack是什么

      先看官方的定義:MessagePack是一種高效的二進制序列化格式。它允許您像JSON一樣在多個語言之間交換數據。但是,它更快并且更小。

       

      從官方定義中,可以有如下的結論:

      1. MessagePack是一個二進制序列化格式,因而它序列化的結果可以在多個語言間進行數據的交換。

      2. 從性能上講,它要比json的序列化格式要好。

      3. 從結果大小上講,它要比json的序列化結果要小。

       

      但是官方并沒有提MessagePack和google pb的對比,實際上從空間和時間兩個方面對比,pb均要優(yōu)于MessagePack,但pb相對MessagePack 的缺點是支持的語言種類比較少,需要編寫專門的 .proto文件,使用上沒有MessagePack方便。

       

      二、MessagePack的主要概念

       

      2.1 type system

      類型體系是MessagePack的基礎,也是MessagePack在序列化后比json占用空間小的關鍵。當前包含的type有如下幾類:
      • Integer represents an integer
      • Nil represents nil
      • Boolean represents true or false
      • Float represents a IEEE 754 double precision floating point number including NaN and Infinity
      • Raw
        • String extending Raw type represents a UTF-8 string
        • Binary extending Raw type represents a byte array
      • Array represents a sequence of objects
      • Map represents key-value pairs of objects
      • Extension represents a tuple of type information and a byte array where type information is an integer whose meaning is defined by applications or MessagePack specification
        • Timestamp represents an instantaneous point on the time-line in the world that is independent from time zones or calendars. Maximum precision is nanoseconds.
       
      這個類型體系將我們在代碼開發(fā)中用到的數據格式進行了映射,并且通過Extension這個類型給使用者留出了自由擴充的空間,但由于表示形式的限制,當前Extension最多有127個。
       
      每一種類型能夠表示的范圍可以查看MessagePack規(guī)范中的Limitation部分和Extension types部分。
       

      2.2 formats

      在MessagePack中一個value的組成格式是這樣的:類型[長度][data]。下面列出幾個示例,詳細完整的描述請看附錄中的MessagePack規(guī)范。
       

      2.2.1常量型

      比如對于null、true、false這三個值,在MessagePack會被固定的映射為如下的值。
      format name
      first byte (in binary)
      first byte (in hex)
      nil
      11000000
      0xc0
      false
      11000010
      0xc2
      true
      11000011
      0xc3

      2.2.2 int型(包含有符號整數和無符號整數)

       
      示例如下
       
      • 0xcc表示當前的值的類型是無符號整數并且長度不超過8個bit,具體的值內容需要通過后續(xù)8個bit位的內容來計算
      • 0xcd表示當前的值的類型是無符號整數并且長度不超過16個bit,具體的值內容需要通過后續(xù)16個bit位的內容來計算
      • 0xd0表示當前的值的類型是有符號整數并且長度不超過8個bit,具體的值內容需要通過后續(xù)8個bit位的內容來計算
      • 0xd1表示當前的值的類型是有符號整數并且長度不超過16個bit,具體的值內容需要通過后續(xù)16個bit位的內容來計算
       
      uint 8 stores a 8-bit unsigned integer  
      +--------+--------+
      |  0xcc  |ZZZZZZZZ|
      +--------+--------+
      
      uint 16 stores a 16-bit big-endian unsigned integer
      +--------+--------+--------+
      |  0xcd  |ZZZZZZZZ|ZZZZZZZZ|
      +--------+--------+--------+
      
      int 8 stores a 8-bit signed integer
      +--------+--------+
      |  0xd0  |ZZZZZZZZ|
      +--------+--------+
      
      int 16 stores a 16-bit big-endian signed integer
      +--------+--------+--------+
      |  0xd1  |ZZZZZZZZ|ZZZZZZZZ|
      +--------+--------+--------+
      

       

      2.2.3 字符串

       
      • 0xd9表示當前的值的類型是字符串并且長度不超過(2^8)-1個bytes ,具體的長度需要通過后續(xù)8個bit位的內容來計算,字符串的具體內容是后續(xù)長度的byte所表示的內容
      • 0xda表示當前的值的類型是字符串并且長度不超過(2^16)-1個bytes ,具體的長度需要通過后續(xù)16個bit位的內容來計算,字符串的具體內容是后續(xù)長度的byte所表示的內容
       
      str 8 stores a byte array whose length is upto (2^8)-1 bytes:
      +--------+--------+========+
      |  0xd9  |YYYYYYYY|  data  |
      +--------+--------+========+
      
      str 16 stores a byte array whose length is upto (2^16)-1 bytes:
      +--------+--------+--------+========+
      |  0xda  |ZZZZZZZZ|ZZZZZZZZ|  data  |
      +--------+--------+--------+========+
       
      

        

      2.2.4 數組

       
      • 0xdc表示當前的值的類型是數組并且長度不超過(2^16)-1個元素 ,具體的長度需要通過后續(xù)16個bit位(兩個byte)的內容來計算,計算出來的值就是數組元素的個數
      • 0xdd表示當前的值的類型是數組并且長度不超過(2^32)-1個元素 ,具體的長度需要通過后續(xù)32個bit位(4個byte)的內容來計算,計算出來的值就是數組元素的個數
       
      array 16 stores an array whose length is upto (2^16)-1 elements:
      +--------+--------+--------+~~~~~~~~~~~~~~~~~+
      |  0xdc  |YYYYYYYY|YYYYYYYY|    N objects    |
      +--------+--------+--------+~~~~~~~~~~~~~~~~~+
      
      array 32 stores an array whose length is upto (2^32)-1 elements:
      +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
      |  0xdd  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|    N objects    |
      +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
      

        

       

      2.2.5 小結

       
       
       

      2.3 Serialization:type to format conversion

       
      source types
      output format
      Integer
      int format family (positive fixint, negative fixint, int 8/16/32/64 or uint 8/16/32/64)
      Nil
      nil
      Boolean
      bool format family (false or true)
      Float
      float format family (float 32/64)
      String
      str format family (fixstr or str 8/16/32)
      Binary
      bin format family (bin 8/16/32)
      Array
      array format family (fixarray or array 16/32)
      Map
      map format family (fixmap or map 16/32)
      Extension
      ext format family (fixext or ext 8/16/32)

       

      If an object can be represented in multiple possible output formats, serializers SHOULD use the format which represents the data in the smallest number of bytes.
       

      2.4 Deserialization: format to type conversion

      source formats
      output type
      positive fixint, negative fixint, int 8/16/32/64 and uint 8/16/32/64
      Integer
      nil
      Nil
      false and true
      Boolean
      float 32/64
      Float
      fixstr and str 8/16/32
      String
      bin 8/16/32
      Binary
      fixarray and array 16/32
      Array
      fixmap map 16/32
      Map
      fixext and ext 8/16/32
      Extension
       

      三、為什么MessagePack比json序列化使用的字節(jié)流更少

       

      3.1 直觀對比

      可以通過下圖的兩張圖簡單進行下對比,第一張圖是同一個數據類型的內容用json和messagepack序列化的結果。
       
       
       
      從第二張圖可以明顯看到messagepack要比json占用的空間更少。
       

      3.2 序列化結果只有value且value進行了專屬映射

       
      這張圖是MessagePack官網上的,用來進行json和MessagePack序列化結果的對比,實際情況是否確實如此呢?
      我本地使用的msgpack-0.6.12版本。
      代碼如下:
       
      public class MessagePackSerializationCompareJson {
      
          @Message // Annotation
          public static class MyMessage {
              // public fields are serialized.
              public boolean compact;
              public int schema;
              
              public  String toString() {
                  return "compact:"+compact+";schema:"+schema;
              }
      
          }
          /**
           * 
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
            //初始化一個對象
              MyMessage src = new MyMessage();
              src.compact = true;
              src.schema=0;
              
            //利用MessagePack進行序列化
              MessagePack msgpack = new MessagePack();
              // Serialize
              byte[] bytes = msgpack.write(src);
              System.out.println("msgpack result length:"+bytes.length);
              
              //利用json進行序列化
              String jsonResult = JSONObject.toJSON(src).toString();
              System.out.println("json result length:"+jsonResult.getBytes().length);
              
          }
      
      }
      

        

       
      運行結果如下:
       
      json result length:27
      msgpack result length:3
      

        

       
      json序列化的結果是27,和官網圖片中的結果相同。但MessagePack的序列化結果是3,要比官網中的數字小很多。
      按照上面圖片的解釋應當是:
      • 第一個byte是82,表示序列化后的結果有兩個元素
      • 第二個byte是c3,表示第一個元素的值是true
      • 第三個byte是00,表示第二個元素的值是0
       
      為了驗證我們的推測,我們可以在MyMessage類中再添加一個boolean類型的屬性,但不給這個屬性賦值,按照java的規(guī)范,這個屬性的值就是false,按照MessagePack的規(guī)范,就會被轉為一個byte的c2,這樣msgpack序列化后的長度值就是4.  而json序列化的增加值要增加不少,是屬性名稱的長度+5(false的長度)+4(要增加兩個雙引號,一個逗號,一個冒號),如果屬性名稱長度是4,則一共會增加13個byte,總長度就是40.
      public class MessagePackSerializationCompareJson {
      
          @Message // Annotation
          public static class MyMessage {
              // public fields are serialized.
              public boolean compact;
              public int schema;
              public boolean link;
              
              
              public  String toString() {
                  return "compact:"+compact+";schema:"+schema+";link:"+link;
              }
      
          }
          /**
           * 
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
            //初始化一個對象
              MyMessage src = new MyMessage();
              src.compact = true;
              src.schema=0;
              
            //利用json進行序列化
              String jsonResult = JSONObject.toJSON(src).toString();
              System.out.println("json result length:"+jsonResult.getBytes().length);
              
            //利用MessagePack進行序列化
              MessagePack msgpack = new MessagePack();
              // Serialize
              byte[] bytes = msgpack.write(src);
              System.out.println("msgpack result length:"+bytes.length);
              
              
              
          }
      
      }
      

        

       
      上面代碼的執(zhí)行的結果也符合猜測:
       
      json result length:40
      msgpack result length:4
      

        

       
      從這個數字上看,MessagePack明顯優(yōu)于json,特別是在屬性多的情況下差距會更大。即使json中把key去掉,序列化后的結果也要比MessagePack占用的空間大。
       

      3.2 序列化對象的屬性順序不能變動

      3.1分析了MessagePack序列化的結果中只包含了value,而不包含key。因而在進行反序列化需要保證類中屬性的順序必須保證完全一致,否則就會出錯:
      如果兩個屬性的類型一致,可以反序列化,但是值發(fā)生錯亂。
      如果兩個屬性的類型不一致,會拋出類型不匹配異常。
       

      3.2.1 順序不同,類型相同

       
      public class SimpleMessagePackPractice {
      
          @Message // Annotation
          public static class MyMessage {
              // public fields are serialized.
              public boolean compact;
              public boolean link;
      
              public String toString() {
                  return "link:" + link + ";compact:" + compact;
              }
          }
      
          @Message // Annotation
          public static class MyMessage2 {
              // public fields are serialized.
              public boolean link;
              public boolean compact;
      
              public String toString() {
                  return "link:" + link + ";compact:" + compact;
              }
          }
      
          /**
           * 
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
      
              //初始化一個對象
              MyMessage src = new MyMessage();
              src.compact = true;
              src.link = false;
      
              //利用MessagePack進行序列化
              MessagePack msgpack = new MessagePack();
              // Serialize
              byte[] bytes = msgpack.write(src);
      
              //利用MessagePack進行反序列化
              MyMessage2 dst = msgpack.read(bytes, MyMessage2.class);
              System.out.println("msgpack 原始數據:" + src);
              System.out.println("msgpack 反序列化:" + dst);
              
              
          }
      
      }
      

        

       
      上述代碼的執(zhí)行結果如下:
      msgpack 原始數據:link:false;compact:true
      msgpack 反序列化:link:true;compact:false
       

      3.2.1 順序不同,類型不同

       
      public class SimpleMessagePackPractice {
      
          @Message // Annotation
          public static class MyMessage {
              // public fields are serialized.
              public boolean compact;
              public String link;
      
              public String toString() {
                  return "link:" + link + ";compact:" + compact;
              }
          }
      
          @Message // Annotation
          public static class MyMessage2 {
              // public fields are serialized.
              public String link;
              public boolean compact;
      
              public String toString() {
                  return "link:" + link + ";compact:" + compact;
              }
          }
      
          /**
           * 
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
      
              //初始化一個對象
              MyMessage src = new MyMessage();
              src.compact = true;
              src.link = "www.baidu.com";
      
              //利用MessagePack進行序列化
              MessagePack msgpack = new MessagePack();
              // Serialize
              byte[] bytes = msgpack.write(src);
      
              //利用MessagePack進行反序列化
              MyMessage2 dst = msgpack.read(bytes, MyMessage2.class);
              System.out.println("msgpack 原始數據:" + src);
              System.out.println("msgpack 反序列化:" + dst);
              
              
          }
      
      }
      

        

       
      執(zhí)行結果:
       
      Exception in thread "main" org.msgpack.MessageTypeException: Expected raw value, but got boolean
      	at org.msgpack.unpacker.Accept.acceptBoolean(Accept.java:33)
      	at org.msgpack.unpacker.MessagePackUnpacker.readOneWithoutStackLarge(MessagePackUnpacker.java:154)
      	at org.msgpack.unpacker.MessagePackUnpacker.readOneWithoutStack(MessagePackUnpacker.java:139)
      	at org.msgpack.unpacker.MessagePackUnpacker.readOne(MessagePackUnpacker.java:73)
      	at org.msgpack.unpacker.MessagePackUnpacker.readString(MessagePackUnpacker.java:502)
      	at org.msgpack.template.StringTemplate.read(StringTemplate.java:46)
      	at org.msgpack.template.StringTemplate.read(StringTemplate.java:25)
      	at org.msgpack.template.AbstractTemplate.read(AbstractTemplate.java:31)
      	at com.my.msgpack.SimpleMessagePackPractice$MyMessage2_$$_Template_1305193908_1.read(SimpleMessagePackPractice$MyMessage2_$$_Template_1305193908_1.java)
      	at org.msgpack.template.AbstractTemplate.read(AbstractTemplate.java:31)
      	at org.msgpack.MessagePack.read(MessagePack.java:388)
      	at org.msgpack.MessagePack.read(MessagePack.java:371)
      	at com.my.msgpack.SimpleMessagePackPractice.main(SimpleMessagePackPractice.java:61)
      

        

       

      參考資料

      1.  

       

      posted on 2018-02-14 21:31  孫振超  閱讀(11821)  評論(3)    收藏  舉報

      主站蜘蛛池模板: 激情人妻自拍中文夜夜嗨| 激情 小说 亚洲 图片 伦| 日韩有码中文在线观看| 无码AV中文字幕久久专区| 亚洲av成人网人人蜜臀| 亚洲色婷婷婷婷五月基地| 久久热在线视频精品视频| 国产精品久久无码一区| 色综合久久综合香蕉色老大| 国产成人一区二区三区免费| 亚洲精品一区二区毛豆| 国产精品无码无需播放器| 国产女人喷潮视频免费| 久久一级精品久熟女人妻| 人妻无码av中文系列久| 人人妻人人做人人爽夜欢视频| 人妻少妇久久中文字幕| 国产精品自拍三级在线观看| 麻豆成人精品国产免费| 亚洲欧美人成网站在线观看看| 国产另类ts人妖一区二区| av无码精品一区二区乱子| 亚洲 中文 欧美 日韩 在线| 特黄特色的大片观看免费视频 | 午夜精品福利亚洲国产| 一道本AV免费不卡播放| 精品一区二区三区自拍图片区| 久久精品国产熟女亚洲av| 亚洲欧洲日韩精品在线| 亚洲色大成网站WWW永久麻豆| 亚洲一区二区av观看| 亚洲精品一二三四区| 俄罗斯老熟妇性爽xxxx| 康保县| 亚洲日本欧洲二区精品| 91亚洲国产三上悠亚在线播放 | 东京热大乱系列无码| 欧美做受视频播放| 国产中文99视频在线观看| 托克逊县| 亚洲精品无码久久一线|