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

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

1、对象序列化后的大小

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

2、序列化与反序列化的速度

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

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

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

从序列化后的大小入手:

测试类:

Java代码  
  1. public class Simple implements java.io.Serializable{
  2. private String name;
  3. private int age;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public void setAge(int age) {
  14. this.age = age;
  15. }
  16. static Simple getSimple() {
  17. Simple simple = new Simple();
  18. simple.setAge(10);
  19. simple.setName("XiaoMing");
  20. return simple;
  21. }
  22. }

Kryo序列化:

Java代码  
  1. Kryo kryo = new Kryo();
  2. kryo.setReferences(false);
  3. kryo.setRegistrationRequired(false);
  4. kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
  5. output.setOutputStream(new FileOutputStream("file.bin"));
  6. kryo.writeClassAndObject(output, Simple.getSimple());
  7. 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序列化:

Java代码  
  1. HessianOutput hout = new HessianOutput(new FileOutputStream("hessian.bin"));
  2. 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值保证这种基本数据类型序列化后尽量小

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

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

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

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

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

表一:

Grammer代码  
  1. # the number of milliseconds since January 1, 1970, 00:00:00 GMT
  2. date       ::= x01 x00 <the number of milliseconds since January 1, 1970, 00:00:00 GMT>
  3. # boolean true/false
  4. boolean ::= x02 x01 # true
  5. ::= x02 x00   # false
  6. # 8-bit binary data
  7. byte       ::= x03 <binary-data>  # binary-data
  8. # char
  9. char       ::= x04 x00 <binary-data>  # binary-data
  10. # short
  11. short   ::= x05 [x00-x7F] [x01-xFF] # 0 to 32767
  12. ::= x05 [x80-xFF] [x01-xFF]  # -23768 to -1
  13. # 32-bit signed integer( + x02 when increment)
  14. int       ::= x06 x01 [x00-x7E]                                 # 0 to 63
  15. ::= x06 x01 [x80-x9E] [x04-xFF]                                  # 64 to 4095
  16. ::= x06 x01 [xA0-xBE] [x00-xFF] [x01-xFF]                    # 4096 to 1048575
  17. ::= x06 x01 [xC0-xDE] [x00-xFF] [x00-xFF] [x01-xFF]              # 1048576 to 268435455
  18. ::= x06 x01 [xE0-xFE] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x07]    # 268435456 to 2147483647
  19. ::= x06 x01 [x01-x7F]                                    # -1 to -64
  20. ::= x06 x01 [x81-x9F] [x04-xFF]                                  # -65 to -4096
  21. ::= x06 x01 [xA1-xBF] [x00-xFF] [x01-xFF]                    # -4097 to -1048576
  22. ::= x06 x01 [xC1-xDF] [x00-xFF] [x00-xFF] [x01-xFF]              # -1048577 to -268435456
  23. ::= x06 x01 [xE1-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x07]    # -268435457 to -2147483648
  24. # 64-bit signed long integer ( +x02 when incerment)
  25. long       ::= x07 x01 [x00-x7E]                                                                                        # 0 to 63
  26. ::= x07 x01 [x80-x8E] [x08-xFF]                                                                              # 64 to 2047
  27. ::= x07 x01 [x90-x9E] [x00-xFF] [x01-xFF]                                                                    # 2048 to 524287
  28. ::= x07 x01 [xA0-xAE] [x00-xFF] [x00-xFF] [x01-xFF]                                                          # 524288 to 134217727
  29. ::= x07 x01 [xB0-xBE] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                                                # 134217728 to 34359738367
  30. ::= x07 x01 [xC0-xCE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                                      # 34359738368 to 8796093022207
  31. ::= x07 x01 [xD0-xDE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                            # 8796093022208 to 2251799813685247
  32. ::= x07 x01 [xE0-xEE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                  # 2251799813685248 to 576460752303423487
  33. ::= x07 x01 [xF0-xFE] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x0F]        # 576460752303423488 to 9223372036854775807
  34. ::= x07 x01 [x01-x7F]                                                                                        # -1 to -64
  35. ::= x07 x01 [x81-x8F] [x08-xFF]                                                                              # -65 to -2048
  36. ::= x07 x01 [x91-x9F] [x00-xFF] [x01-xFF]                                                                    # -2049 to -524288
  37. ::= x07 x01 [xA1-xAF] [x00-xFF] [x00-xFF] [x01-xFF]                                                          # -524289 to -134217728
  38. ::= x07 x01 [xB1-xBF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                                                # -134217729 to -34359738368
  39. ::= x07 x01 [xC1-xCF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                                      # -34359738369 to -8796093022208
  40. ::= x07 x01 [xD1-xDF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                            # -8796093022209 to -2251799813685248
  41. ::= x07 x01 [xE1-xEF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-xFF]                  # -2251799813685249 to -576460752303423488
  42. ::= x07 x01 [xF1-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x00-xFF] [x01-x0F]        # -576460752303423489 to -9223372036854775808
  43. # float/Float
  44. float      ::= x08 x01 <floatToInt>
  45. # double/Double
  46. double     ::= x09 x01 <doubleToLong>
  47. # String
  48. String     ::= x0A x01 x82 <utf8-data>                                                                    # data.length()=1
  49. ::= x0A x01 <utf8-data.subString(0,data.length()-2)> <utf8-data.charAt(data.length-1)>+x70   # data.length()>1
  50. # The class not registered in kryo
  51. Object  ::= x01 x00 <(string)className> <(byte)id> <(Object)objectFieldValue ordered by fieldName>

Kryo为什么比Hessian快相关推荐

  1. Kryo 为什么比 Hessian 快

    Kryo 是一个快速高效的Java对象图形序列化框架,它原生支持java,且在java的序列化上甚至优于google著名的序列化框架protobuf.由于 protobuf需要编写Schema文件(. ...

  2. 分布式系统开发工具包 —— 基于Kryo的Java对象序列化

    Kryo是用于Java语言的一个快速和高效的对象图序列化框架.Kryo项目的目的是快速.高效.方便地使用API.当需要持久化对象的时候,不论是持久化到文件.数据库还是网络,都可以使用Kryo. 目前K ...

  3. 咋搭建域控服务器,Active Directory虚拟机搭建域控服务器环境

    前言 还是和上一章一样,痛苦过后还是记录下给后来人提供便利为妙. 虚拟机选择:建议Hyper-V或者VMware 系统选择:建议WIindows Server 2003及以上 我这里是使用VMware ...

  4. 跨语言RPC框架Hessian、Thrift、Protocol Buffer之间的选择

    为什么80%的码农都做不了架构师?>>>    总结在几者之间选择的考量: 1. 如果你不需要很多语言相互调用, 希望保持清晰的java接口代码(无任何业务不相关的接口继承和方法,属 ...

  5. Spark的性能调优

    下面这些关于Spark的性能调优项,有的是来自官方的,有的是来自别的的工程师,有的则是我自己总结的. 基本概念和原则 首先,要搞清楚Spark的几个基本概念和原则,否则系统的性能调优无从谈起: 每一台 ...

  6. 解析 PowerJob 的序列化方案

    作者 | HelloGitHub 来源 | HelloGitHub(ID:GitHub520) 头图 | CSDN 下载自视觉中国 序列化与反序列化一直是分布式编程中无法绕开的话题.PowerJob ...

  7. Spark面试,Spark面试题,Spark面试汇总

    Table of Contents 1.你觉得spark 可以完全替代hadoop 么? 2.Spark消费 Kafka,分布式的情况下,如何保证消息的顺序? 3.对于 Spark 中的数据倾斜问题你 ...

  8. spark笔记spark优化

    基本概念(Basic Concepts) RDD - resillient distributed dataset 弹性分布式数据集 Operation - 作用于RDD的各种操作分为transfor ...

  9. 大数据技术之_19_Spark学习_07_Spark 性能调优 + 数据倾斜调优 + 运行资源调优 + 程序开发调优 + Shuffle 调优 + GC 调优 + Spark 企业应用案例

    大数据技术之_19_Spark学习_07 第1章 Spark 性能优化 1.1 调优基本原则 1.1.1 基本概念和原则 1.1.2 性能监控方式 1.1.3 调优要点 1.2 数据倾斜优化 1.2. ...

最新文章

  1. POJ1149 PIGS
  2. [Linux] 进程间通信
  3. java实现验证码图片_java实现验证码图片
  4. 2021年中国高精地图产业研究分析
  5. 左耳朵耗子:如何超过大多数人
  6. Win10下安装Ubuntu16.04-空间不可用-个人志
  7. 封闭实验的对称不变性——思想实验推导狭义相对论(五)
  8. 异构符号网络上的情感链接预测——SHINE
  9. Android app 启动优化
  10. JavaScript中如何删除节点?
  11. 通过slave_exec_mode=IDEMPOTENT跳过主从复制中的错误
  12. 个人职业生涯规划发展的一些图
  13. 线程安全问题及解决方法
  14. 极链科技联合阿里云发布视联网平台解决方案
  15. nuitka打包命令解释
  16. 两个人在一起的相处之道
  17. Linux入门篇——进程
  18. ideal怎么刷新文件夹
  19. 数学专业的数学与计算机专业的数学的比较
  20. 中南民族大学计算机技术专硕读几年,中南民族大学专业硕士学费一般多少

热门文章

  1. swap,交换,第三随笔
  2. 萌龙大乱斗 合成表 持续更新
  3. 网页速度很慢优化方案:如何提高网页加载速度,提升网站加载速度
  4. 深入探索PowerPivot客户端和服务器端架构
  5. linux文件比较,合并,查找重复行
  6. 已经push的如何回退_如何撤回Git push 到远程分支以后的方法
  7. 30号晚直播丨数据操作加速器,CloudQuery v1.3.5 发布!
  8. 新年寄语 | 2018 以及 Oracle 18c 一个时代的开启
  9. 快来一起玩转LiteOS组件:RHas
  10. 面试官:你知道怎么求素数吗?