我在 Scala 中广泛使用 Chronicle Map,最近决定尝试 Kryo 序列化。我添加了自定义编组器(下面的代码),虽然它将我的商店大小减少了 14G(大约 62%),并且一切仍然正常,但速度令人无法接受。
我创建了一个示例用例并对相同的数据进行了几次运行
[Using kryo] took 6883, and then 7187, 6954, 7225, 13051
[Not using kryo] took 2326, and then 1352, 1493, 1500, 1187
所以它慢了好几倍。这是用于阅读的编组器:
class KryoMarshallerReader[T] extends BytesReader[T] {
val kryo = // Reference to KryoPool from Twitter's Chill library
override def read(in: Bytes[_], using: T): T = {
val bytes = benchmark("array allocation") {
new Array[Byte](in.readRemaining().toInt)
}
benchmark("reading bytes") {
in.read(bytes)
}
benchmark("deserialising") {
kryo.fromBytes(bytes).asInstanceOf[T]
}
}
override def readMarshallable(wire: WireIn): Unit = {}
override def writeMarshallable(wire: WireOut): Unit = {}
}
然后我平均了这三个阶段的执行时间(以毫秒为单位),并意识到读取字节是最慢的:
stage Average time (ms)
(fctr) (dbl)
1 [array allocation] 0.9432907
2 [deserialising] 0.9944112
3 [reading bytes] 13.2367265
现在的问题是——我做错了什么?
我查看了界面,Bytes[_]
它看起来像是一个一个地读取字节 - 有没有办法使用缓冲区或能够神奇地批量加载的东西?
更新:最终我将数组分配+读取字节更改为in.toByteArray
但它仍然很慢,因为它在引擎盖下一个接一个地复制字节。仅在地图上运行读取表明字节读取是瓶颈: