C轮融资|Fury:一个基于JIT动态编译的高性能多语言原生序列化框架( 七 )




性能比较(数值越小越好)
这里给出在纯Java序列化场景对比其它框架的性能测试结果 。 其它语言的性能测试将在后续文章当中发布 。
测试环境:
操作系统:4.9.151-015.ali3000.alios7.x86_64 CPU型号:Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz Byte Order:Little Endian L1d cache:32K L1i cache:32K L2 cache:1024K L3 cache:33792K 测试原则:
自定义类型序列化测试数据使用的是kryo-benchmark[8
的数据 , 保证测试结果对Fury没有任何偏向性 。 尽管Kryo测试数据里面有大量基本类型数组 , 为了保证测试的公平性我们并没有开启Fury的Out-Of-Band零拷贝序列化能力 。 然后使用我们自己创建的对象单独准备了一组零拷贝测试用例 。
测试工具:
为了避免JVM JIT给测试带来的影响 , 我们使用JMH[9
工具进行测试 , 每组测试在五个子进程依次进行 , 避免受到进程CPU调度的影响 , 同时每个进程里面执行三组Warmup和5组正式测试 , 避免受到偶然的环境波动影响 。
下面是我们使用JMH测试fury/kryo/fst/hession/protostuff/jdk序列化框架在序列化到堆内存和堆外内存时的性能(数值越小越好) 。
自定义类型性能对比
Struct
Struct类型主要是有纯基本类型的字段组成 , 对于这类对象 , Fury通过JIT等技术 , 可以达到Kryo 20倍的性能 。
public class Struct implements Serializable { int f1; long f2; float f3; double f4; ... int f97; long f98; float f99; double f100; 序列化:


反序列化:


Sample
Sample类型主要由基本类型、装箱类型、字符串和数组等类型字段组成 , 对于这种类型的对象 , Fury的性能可以达到Kryo的6~7倍 。 没有更快的原因是因为这里的多个基本类型数组需要进行拷贝 , 这块占用一定的耗时 。 如果使用Fury的Out-Of-Band序列化的话 。 这些额外的拷贝就可以完全避免掉 , 但这样比较不太公平 , 因此这里没有开启 。
public final class Sample implements Serializable { public int intValue; public long longValue; public float floatValue; public double doubleValue; public short shortValue; public char charValue; public boolean booleanValue; public Integer IntValue; public Long LongValue; public Float FloatValue; public Double DoubleValue; public Short ShortValue; public Character CharValue; public Boolean BooleanValue; public int[
intArray; public long[
longArray; public float[
floatArray; public double[
doubleArray; public short[
shortArray; public char[
charArray; public boolean[
booleanArray; public String string; // Can be null. public Sample sample; // Can be null. public Sample() { public Sample populate(boolean circularReference) { intValue = https://mparticle.uc.cn/api/123; longValue = 1230000; floatValue = 12.345f; doubleValue = 1.234567; shortValue = 12345; charValue ='!'; booleanValue = https://mparticle.uc.cn/api/true; IntValue = 321; LongValue = 3210000L; FloatValue = 54.321f; DoubleValue = 7.654321; ShortValue = 32100; CharValue ='$'; BooleanValue = https://mparticle.uc.cn/api/Boolean.FALSE; intArray = new int[
{-1234 -123 -12 -1 0 1 12 123 1234; longArray = new long[
{-123400 -12300 -1200 -100 0 100 1200 12300 123400; floatArray = new float[
{-12.34f -12.3f -12 -1 0 1 12 12.3f 12.34f; doubleArray = new double[
{-1.234 -1.23 -12 -1 0 1 12 1.23 1.234; shortArray = new short[
{-1234 -123 -12 -1 0 1 12 123 1234; charArray = \"asdfASDF\".toCharArray(); booleanArray = new boolean[
{true false false true; string = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"; if (circularReference) { sample = this;return this;序列化耗时:


反序列化耗时:


MediaContent
对于MediaContent这类包含大量String的数据结构 , Fury性能大概是Kryo的4~5倍 。 没有更快的原因是因为String序列化开销比较大 , 部分摊平了Fury JIT带来的性能提升 。 用户如果对String序列化有更好的性能要求的话 , 可以使用Fury的String零拷贝序列化协议 , 在序列化时直接把String内部的Buffer抽取出来 , 然后直接放到Out-Of-Band buffer里面 , 完全避免掉String序列化的开销 。