别的不说,先上两张图,这两张图是jvm序列化对比测试(github.com/eishay/jvm-…
如图所示,我们的glowworm并未名列前茅,可以说只是排名中上游,但你依然可以在glowworm排名的周围看到大名鼎鼎的protobuf。 mmbiz.qpic.cn/mmbiz_png/R…
图1.序列化+反序列化的时间
图2.序列化后的大小(byte)
怎么使用glowworm
User user = new User(); byte[] bytes = PB.toPBBytes(user); User result = (User)PB.parsePBBytes(bytes);
这里需要注意一下,glowworm现在的方案是默认写入类名!
这就是最简单的使用方式,PB.toPBBytes(obj)进行序列化,PB.parsePBBytes(bytes, clazz)进行反序列化。反序列化的两个参数分别是序列化之后得到的byte[],和需要反序列化的类型。
如果觉得每次把类名写入到byte[]中比较消耗大小的话,可以手动设定不传类名,那么在反序列化时就需要传入class参数,来告诉glowworm需要反序列化的是哪个类。方法如下:
User user = new User(); Parameters p = new Parameters(); p.setNeedWriteClassName(false); byte[] bytes = PB.toPBBytes(user, p); User result = PB.parsePBBytes(bytes,p);
需要设定一个参数Parameters,指定needWriteClassName = false即可。
当然如果看了源码的话,发现这个Parameters参数中还可以设定编码,默认为utf-8。Parameters这个参数现在暂时只有这两个用途,如果以后遇到一些特殊的需求,会在这个参数里进行添加。
maven相关
已上传至sonatype.org,如有需要可以配置仓库地址: sonatype-nexus-snapshots Sonatype Nexus Snapshots oss.sonatype.org/content/rep… false true com.jd.dd glowworm 1.0-SNAPSHOT
glowworm是怎么做的
开发glowworm的初衷
众所周知,google的protobuf(code.google.com/p/protobuf/…
protobuf无论从性能还是大小来说都是出类拔萃的, 但是我们不得不为每一个user javabean编写对应的proto文件。其实编写proto文件本身无可厚非,序列化就是一个通过解析对象结构把对象转成byte流的过程,解析对象结果本身很是繁琐,耗时耗力。所以protobuf用一个外部文件记录这个对象结构,那么每次遇到相同结构的对象时就省去了再次解析的过程,而且还能跨语言。
对此,fastjson(code.alibabatech.com/wiki/displa… description language)文件,对于对象结构的解析会在第一次进行序列化的时候进行,通过asm新建一个这个序列化器的class并保存下来,供以后复用。
但是作为序列化组件fastjson有一个天生的短板,就是json是以字符串进行传输的,而字符串在转化成byte占用了很大的空间,所以即便是强如fastjson也无法把序列化之后的文件大小缩减到很低的水平。从图2中可以看到排名下半部分的都是基于xml或json格式进行序列化的组件,而上半部分多是直接把对象转成byte数组。
为什么不能集合protobuf和fastjson各自的优点开发一个序列化组件,做到既能保证大小又能兼顾性能、而且使用起来轻便快捷呢?。glowworm应运而生。
glowworm的特点
1.不依赖第三方库 2.无需编写idl文件 3.支持各种数据类型 4.整体架构优秀 5.基于byte数组的序列化方案
glowworm支持的类型
1.所有基本类型 2.用户自定义的javabean 3.支持数组,常用的List、Set、Map 4.支持一些特殊类型,现阶段支持的还比较有限,索性就都列在下面了:Date, Time, Timestamp, Enum, InetAddress, AtomicBoolean, AtomicInteger, AtomiceLong, BigDecimal, BigInteger, Class, Exception 5.对泛型有优化,鼓励使用泛型 6.完美支持引用,包括循环引用
glowworm的架构
图3、图4分别是序列化和反序列化的流程