Kryo序列化

在上一篇博文中提到,Spark任务中,使用序列化数据的方式对增加其执行效率有很大的作用。并且由于Kryo序列化方式在主动注册自定义类的情况下,无论是序列化速度还是序列化结果的大小,都比Java自身的序列化方式要好。在这篇文章中将根据代码实例来纵向对比Kryo在注册了自定义类、没有注册自定义类下的序列化结果,以及横向对比Kryo和Java两者序列化的时间和结果。

Kryo横向对比

本小节通过使用Kryo和Java两种序列化方式对统一对象进行序列化,并观察其在序列化过程中所用的时间长短及序列化后结果的大小,以此作为判断其性能优劣的指标。验证代码如下:

class TestKryo$Test extends FunSuite {
    test("KryoTest"){
        val filledArray: Array[Position] = Array.fill(1000)(new Position(0.2,0.3))
        val kryo: Kryo = new Kryo()
        kryo.register(classOf[recruit.scalar.com.elevenbee.work.bean.model.personcluster.Position])//手动注册
        kryo.register(classOf[Array[Position]])
        kryo.setReferences(false)
        kryo.setInstantiatorStrategy(new StdInstantiatorStrategy)
        val output: Output = new Output()
        val outPutStream: BufferedOutputStream = new BufferedOutputStream(new FileOutputStream("byte.bin"))
        output.setOutputStream(outPutStream)
        val bytes: Array[Byte] = new Array[Byte](1000000)
        output.setBuffer(bytes)
        val stopwatch: Stopwatch = Stopwatch.createStarted()
        kryo.writeClassAndObject(output,filledArray)
        println("Kryo序列化所用时间 "+stopwatch.elapsed(TimeUnit.MILLISECONDS))
        println("Kryo序列化后的字节数组大小为 "+bytes.count(_!='\0'))
        println("Kryo序列化后的结果为")
        println(new String(bytes))

        val byteArrayOutputStream: ByteArrayOutputStream = new ByteArrayOutputStream(1000000)
        val objectOutputStream: ObjectOutputStream = new ObjectOutputStream(byteArrayOutputStream)
        stopwatch.reset()
        stopwatch.start()
        objectOutputStream.writeObject(filledArray)
        println("Java序列化所用时间 "+stopwatch.elapsed(TimeUnit.MILLISECONDS))
        val byteArray: Array[Byte] = byteArrayOutputStream.toByteArray
        println("Java序列化后的字节数组大小为 "+byteArrayOutputStream.toByteArray.count(_!='\0'))
        println("Java序列化后的字节数组结果为")
        println(new String(byteArray))

        output.close()
        outPutStream.close()
    }
}

可以看到,在代码中使用两种序列化方式对同一个Array进行序列化,并打印了其序列化时间及结果,运行结果如下:

Kryo序列化所用时间 17
Kryo序列化后的字节数组大小为 17003
Kryo序列化后的结果为
�?�333333?ə�����?�333333?ə�����...重复一千次
Java序列化所用时间 112
Java序列化后的字节数组大小为 20177
Java序列化后的字节数组结果为
�� ur F[Lrecruit.scalar.com.elevenbee.work.bean.model.personcluster.Position;a)����  xp  �sr Crecruit.scalar.com.elevenbee.work.bean.model.personcluster.Position)�47��� D latD lngxp?�333333?ə�����sq ~ ...重复一千次

可以看到,在手动向Kryo注册了Array和Position类后,Kryo无论是序列化时间还是序列化结果都比Java的序列化要优秀很多。

纵向对比

纵向对比主要对比Kryo 在主动注册自定义类和不注册自定义类的情况下,其各自的序列化效率。

class TestKryo$Test extends FunSuite {
    test("KryoTest"){
        val filledArray: Array[Position] = Array.fill(1000)(new Position(0.2,0.3))
        val kryo: Kryo = new Kryo()
        kryo.register(classOf[recruit.scalar.com.elevenbee.work.bean.model.personcluster.Position])//手动注册
        kryo.register(classOf[Array[Position]])
        kryo.setReferences(false)
        kryo.setInstantiatorStrategy(new StdInstantiatorStrategy)
        val output: Output = new Output()
        val bytes: Array[Byte] = new Array[Byte](1000000)
        output.setBuffer(bytes)
        val stopwatch: Stopwatch = Stopwatch.createStarted()
        kryo.writeClassAndObject(output,filledArray)
        println("Kryo序列化所用时间 "+stopwatch.elapsed(TimeUnit.MILLISECONDS))
        println("Kryo序列化后的字节数组大小为 "+bytes.count(_!='\0'))
        println("Kryo序列化后的结果为")
        println(new String(bytes))
        output.close()
    }
}

测试代码如上所示,注册了全部的自定义类后的序列化结果正如横向对比中所示,不再赘述。这里测试在不注册其中两个自定义类的情况下,其序列化效率。在不注册Array而注册Position的情况下,序列化结果如下所示:

Kryo序列化所用时间 71
Kryo序列化后的字节数组大小为 17075
Kryo序列化后的结果为
 �[Lrecruit.scalar.com.elevenbee.work.bean.model.personcluster.Position;�?�333333?ə�����...重复1000

可以看到序列化内容中增加了一段全限定名表示是Position的数组类型,并且序列化时间瞬间涨了4倍多。在不注册Position而注册了Array的情况下的情况下,序列化信息如下所示:

Kryo序列化所用时间 64
Kryo序列化后的字节数组大小为 17072
Kryo序列化后的结果为
� �recruit.scalar.com.elevenbee.work.bean.model.personcluster.Position?�333333?ə�����...重复1000

可以看到其序列化内容与只注册Position的大小类似,且序列化时间也差不多。在两者都不注册的情况下,其序列化信息如下

Kryo序列化所用时间 74
Kryo序列化后的字节数组大小为 18144
Kryo序列化后的结果为
 �[Lrecruit.scalar.com.elevenbee.work.bean.model.personcluster.Position;��recruit.scalar.com.elevenbee.work.bean.model.personcluster.Position?�333333?ə�����...重复1000

可以看到无论是序列化时间还是序列化内容都会增加。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值