Kryo與Hessian的序列化比較

來源:互聯網
上載者:User

轉載地址:http://x-rip.iteye.com/blog/1555344

Kryo 是一個快速高效的Java對象圖形序列化架構,它原生支援java,且在java的序列化上甚至優於google著名的序列化架構protobuf。由於protobuf需要編寫Schema檔案(.proto),且需靜態編譯。故選擇與Kryo類似的序列化架構Hessian作為比較來瞭解一下Kryo為什麼這麼快。

序列化的過程中主要有3個指標:

1、對象序列化後的大小

一個對象會被序列化工具序列化為一串byte數組,這其中包含了對象的field值以及中繼資料資訊,使其可以被還原序列化回一個對象

2、序列化與還原序列化的速度

一個對象被序列化成byte數組的時間取決於它產生/解析byte數組的方法

3、序列化工具本身的速度

序列化工具本身建立會有一定的消耗。

 

從序列化後的大小入手:

測試類別:

public class Simple implements java.io.Serializable{  private String name;  private int age;  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public int getAge() {    return age;  }  public void setAge(int age) {    this.age = age;  }  static Simple getSimple() {    Simple simple = new Simple();    simple.setAge(10);    simple.setName("XiaoMing");    return simple;  }}

 Kryo序列化:

    Kryo kryo = new Kryo();    kryo.setReferences(false);    kryo.setRegistrationRequired(false);    kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());    output.setOutputStream(new FileOutputStream("file.bin"));    kryo.writeClassAndObject(output, Simple.getSimple());    output.flush();

查看序列化後的結果:

紅色部分:對象頭,01 00代表一個未註冊過的類

黑色部分:對象所屬的class的名字(kryo中沒有設定某個欄位的結束符,對於String這種不定長的byte數組,kryo會在其最後一個byte位元組加上x70,如類名最後一位為e,其askii碼為x65,在其基礎上加x70,即為E5)

綠色部分:表示這個對象在對象圖中的id。即simple對象在對象圖中的id為01.

藍色部分:表示該類的field。其中02 14中14表示int數值10(映射關係見表1),02和綠色部分的01意思是一樣的,即10這個int對象在對象圖中的id為02。以此類推,03表示對象圖中的第三個對象,即XiaoMing這個String,同樣其最後一位byte被加了x70。

Hessian序列化:

    HessianOutput hout = new HessianOutput(new FileOutputStream("hessian.bin"));    hout.writeObject(Simple.getSimple());

 

查看序列化後的結果:

紅色部分: 對象頭

黑色部分: 對象所屬的類名(類名的askii碼)

紫色部分: 位元組類型描述元,表示之後的位元組屬於何種類型,53表示String,49表示int,等等

綠色部分: 位元組長度描述符,用於表示後面的多少個位元組是表示該位元組組的

白色部分: field實際的類型的byte值

藍色部分: filed實際的value

7A: 結束符

從序列化後的位元組可以看出以下幾點:

1、Kryo序列化後比Hessian小很多。(kryo優於hessian)

2、由於Kryo沒有將類field的描述資訊序列化,所以Kryo需要以自己載入該類的filed。這意味著如果該類沒有在kryo中註冊,或者該類是第一次被kryo序列化時,kryo需要時間去載入該類(hessian優於kryo)

3、由於2的原因,如果該類已經被kryo載入過,那麼kryo儲存了其類的資訊,就可以很快的將byte數組填入到類的field中,而hessian則需要解析序列化後的byte數組中的field資訊,對於序列化過的類,kryo優於hessian。

4、hessian使用了固定長度儲存int和long,而kryo則使用的變長,實際中,很大的資料不會經常出現。(kryo優於hessian)

5、hessian將序列化的欄位長度寫入來確定一段field的結束,而kryo對於String將其最後一位byte+x70用於標識結束(kryo優於hessian)

 

總上所述:

kryo為了保證序列化的高效性,會載入需要序列化的類,這會帶來一定的消耗。可以理解為kryo本身的消耗。由於這點消耗從而可以保證序列化後的大小(避免不必要的來源資料)比較小和快速的還原序列化。

通過變長的int和long值保證這種基礎資料型別 (Elementary Data Type)序列化後盡量小

通過最後一位的特殊操作而非寫入長度來標記欄位的範圍

本篇未涉及到的地方還有:

使用開源工具reflectasm進行反射而非java本身的反射

使用objenesis來建立無預設建構函式的類的對象

由於kryo目前只支援Java,所以官方文檔也沒有給出它序列化所用的kryo grammer,預設支援以下十種。見表一

表一:

 

           # the number of milliseconds since January 1, 1970, 00:00:00 GMTdate       ::= x01 x00 <the number of milliseconds since January 1, 1970, 00:00:00 GMT>           # boolean true/falseboolean ::= x02 x01# true              ::= x02 x00# false      # 8-bit binary databyte   ::= x03 <binary-data># binary-data     # charchar   ::= x04 x00 <binary-data># binary-data     # shortshort   ::= x05 [x00-x7F] [x01-xFF]# 0 to 32767    ::= x05 [x80-xFF] [x01-xFF]# -23768 to -1              # 32-bit signed integer( + x02 when increment)int       ::= x06 x01 [x00-x7E]# 0 to 63           ::= x06 x01 [x80-x9E] [x04-xFF]          # 64 to 4095           ::= x06 x01 [xA0-xBE] [x00-xFF] [x01-xFF]       # 4096 to 1048575           ::= x06 x01 [xC0-xDE] [x00-xFF] [x00-xFF] [x01-xFF]      # 1048576 to 268435455   ::= x06 x01 [xE0-xFE] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x07]  # 268435456 to 2147483647           ::= x06 x01 [x01-x7F]# -1 to -64           ::= x06 x01 [x81-x9F] [x04-xFF]          # -65 to -4096           ::= x06 x01 [xA1-xBF] [x00-xFF] [x01-xFF]       # -4097 to -1048576           ::= x06 x01 [xC1-xDF] [x00-xFF] [x00-xFF] [x01-xFF]      # -1048577 to -268435456           ::= x06 x01 [xE1-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x07]  # -268435457 to -2147483648      # 64-bit signed long integer ( +x02 when incerment)long       ::= x07 x01 [x00-x7E]# 0 to 63           ::= x07 x01 [x80-x8E] [x08-xFF]          # 64 to 2047           ::= x07 x01 [x90-x9E] [x00-xFF] [x01-xFF]       # 2048 to 524287           ::= x07 x01 [xA0-xAE] [x00-xFF] [x00-xFF] [x01-xFF]      # 524288 to 134217727           ::= x07 x01 [xB0-xBE] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # 134217728 to 34359738367   ::= x07 x01 [xC0-xCE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # 34359738368 to 8796093022207           ::= x07 x01 [xD0-xDE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # 8796093022208 to 2251799813685247   ::= x07 x01 [xE0-xEE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # 2251799813685248 to 576460752303423487   ::= x07 x01 [xF0-xFE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x0F]      # 576460752303423488 to 9223372036854775807   ::= x07 x01 [x01-x7F]# -1 to -64           ::= x07 x01 [x81-x8F] [x08-xFF]          # -65 to -2048           ::= x07 x01 [x91-x9F] [x00-xFF] [x01-xFF]       # -2049 to -524288           ::= x07 x01 [xA1-xAF] [x00-xFF] [x00-xFF] [x01-xFF]      # -524289 to -134217728           ::= x07 x01 [xB1-xBF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # -134217729 to -34359738368   ::= x07 x01 [xC1-xCF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # -34359738369 to -8796093022208   ::= x07 x01 [xD1-xDF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # -8796093022209 to -2251799813685248   ::= x07 x01 [xE1-xEF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]      # -2251799813685249 to -576460752303423488   ::= x07 x01 [xF1-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x0F]      # -576460752303423489 to -9223372036854775808     # float/Floatfloat      ::= x08 x01 <floatToInt>   # double/Doubledouble     ::= x09 x01 <doubleToLong>   # StringString     ::= x0A x01 x82 <utf8-data># data.length()=1   ::= x0A x01 <utf8-data.subString(0,data.length()-2)> <utf8-data.charAt(data.length-1)>+x70# data.length()>1        # The class not registered in kryoObject::= x01 x00 <(string)className> <(byte)id> <(Object)objectFieldValue ordered by fieldName> 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.