Kryo 是一个快速高效的Java对象图形序列化框架,它原生支持java,且在java的序列化上甚至优于google著名的序列化框架protobuf。由于 protobuf需要编写Schema文件(.proto),且需静态编译。故选择与Kryo类似的序列化框架Hessian作为比较来了解一下Kryo 为什么这么快。

序列化的过程中主要有3个指标:

1、对象序列化后的大小
一个对象会被序列化工具序列化为一串byte数组,这其中包含了对象的field值以及元数据信息,使其可以被反序列化回一个对象

2、序列化与反序列化的速度
一个对象被序列化成byte数组的时间取决于它生成/解析byte数组的方法

3、序列化工具本身的速度
序列化工具本身创建会有一定的消耗。

从序列化后的大小入手:

测试类:

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
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序列化:

1
2
3
4
5
6
7
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序列化:

1
2
HessianOutput hout = new HessianOutput(new FileOutputStream("hessian.bin")); 
hout.writeObject(Simple.getSimple()); <span></span><span></span>

查看序列化后的结果:

红色部分: 对象头

黑色部分: 对象所属的类名(类名的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值保证这种基本数据类型序列化后尽量小

通过最后一位的特殊操作而非写入长度来标记字段的范围

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

使用开源工具reflectasm进行反射而非java本身的反射

使用objenesis来创建无默认构造函数的类的对象

由于kryo目前只支持Java,所以官方文档也没有给出它序列化所用的kryo grammer,默认支持以下十种。见表一

表一:

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
# the number of milliseconds since January 1, 1970, 00:00:00 GMT
date       ::= x01 x00 <the number of milliseconds since January 1, 1970, 00:00:00 GMT>
 
           # boolean true/false
boolean ::= x02 x01 # true
              ::= x02 x00   # false
            
           # 8-bit binary data
byte       ::= x03 <binary-data>  # binary-data 
 
           # char
char       ::= x04 x00 <binary-data>  # binary-data 
     
           # short
short   ::= 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/Float
float      ::= x08 x01 <floatToInt>
 
           # double/Double
double     ::= x09 x01 <doubleToLong>
 
           # String
String     ::= 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 kryo
Object  ::= x01 x00 <(string)className> <(byte)id> <(Object)objectFieldValue ordered by fieldName>

via http://x-rip.iteye.com/blog/1555344

Kryo 为什么比 Hessian 快的更多相关文章

  1. Java 序列化界新贵 kryo 和熟悉的“老大哥”,就是 PowerJob 的序列化方案

    本文适合有 Java 基础知识的人群 作者:HelloGitHub-Salieri HelloGitHub 推出的<讲解开源项目>系列. 项目地址: https://github.com/ ...

  2. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  3. 基于apache的tomcat负载均衡和集群配置session共享

    接上面的话题接着继续完善.为什么没接到上篇呢?原因很简单太长的文章不爱看!就像有人写了上千行的方法一样,不是逼得没办法谁爱看谁看,反正我不看. 期间我没有一次配置成功,从失败的开始说起, 1.准备ja ...

  4. Netty实现高性能RPC服务器

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  5. 【Spark学习】Apache Spark调优

    Spark版本:1.1.0 本文系以开源中国社区的译文为基础,结合官方文档翻译修订而来,转载请注明以下链接: http://www.cnblogs.com/zhangningbo/p/4117981. ...

  6. Spark的性能调优杂谈

    下面这些关于Spark的性能调优项,有的是来自官方的,有的是来自别的的工程师,有的则是我自己总结的. 基本概念和原则 <1>  每一台host上面可以并行N个worker,每一个worke ...

  7. Spark 调优(转)

    Spark 调优 返回原文英文原文:Tuning Spark Because of the in-memory nature of most Spark computations, Spark pro ...

  8. 基于Memcached的tomcat集群session共享所用的jar

    多个tomcat各种序列化策略配置如下:一.java默认序列化tomcat配置conf/context.xml添加<Manager className="de.javakaffee.w ...

  9. 【译】Spark调优

    原文地址:http://spark.incubator.apache.org/docs/0.7.3/tuning.html 译文地址:http://www.oschina.net/translate/ ...

随机推荐

  1. Unity3d 协程、调用函数、委托

    (一)协程 开启方法:StartCoroutine("函数名"): 结束方法StopCoroutine("函数名"),StopAllCoroutines(); ...

  2. I/O 流---输出流

    输出流(写入数据) a. 字节输出流 OutputStram 输出流的父类 FileOutputStream:  继承OutputStream 方法: OutputStream os=new File ...

  3. 1041: [HAOI2008]圆上的整点 - BZOJ

    Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数.Input rOutput 整点个数Sample Input4Sample Output4HINT n ...

  4. myeclipse报错:Could not create the view: An unexpected exception was thrown.

    打开server窗口,发现显示:Could not create the view: An unexpected exception was thrown. 此处解决方法: 关闭myeclipse 删 ...

  5. 极客范:如何使用 Cloud Insight 来监控闭路电视?

    最近新上线支持 Windows 系统及其组件 监控功能的 Cloud Insight,在系统监控领域基本囊括了对所有主流和部分非主流平台的支持.但是这还不够,Cloud Insight 可不仅仅是一个 ...

  6. linux的定时任务crontab

    每隔一分钟执行以下语句: #打印当前时间: date "+%Y-%m-%d %T" 保存为/usr/test/test.sh 查看系统中当前用户有多少个定时任务: crontab ...

  7. 在其他的电脑上配置绿色Jre+tomcat运行环境

    其他的同事要使用我们的web程序(基于tomcat的web程序).所以要求是对方的电脑任何程序都不需要安装,把我们的包拷贝过去,直接执行批处理就可以运行. 经过了一番摸索,实现方式如下: 1,准备jr ...

  8. QT的QWidget和Delphi的TPanel很像,都是万能的基础控件

    都只提供了最基本的功能,实际可以在上面随心所欲的创造新的控件.而自身也已经拥有基础的显示功能,而TCustomControl就不行. 比如,这样使用QWidget,直接就可以显示: void Main ...

  9. node.js 异步式I/O 与事件驱动

    Node.js 最大的特点就是异步式 I/O(或者非阻塞 I/O)与事件紧密结合的编程模式.这种模式与传统的同步式 I/O 线性的编程思路有很大的不同,因为控制流很大程度上要靠事件和回调函数来组织,一 ...

  10. 【运维手记】virtualbox中centOS安装增强功能

    在virtualbox安装了centOS,想安装增强功能时,系统提示: building the main Guest Additions module Failed 于是尝试了以下两步操作: (1) ...