用Java序列化多个巨大的地图

时间:2017-11-27 11:53:11

标签: java dictionary serialization hashmap

我想序列化多个映射,其中键类型为BitSet,值为List。目前有8个地图,每个地图有~430k个元素。每个密钥都是一个包含4096位的位集。

我的问题在于生成文件的大小,而不是程序本身。 每当我以标准方式执行此操作时:

    SerializationUtils.ensurePathExists(filePath);
    DeflaterOutputStream fstream = new DeflaterOutputStream(new FileOutputStream(filePath.toFile()));
    ObjectOutputStream ostream = new ObjectOutputStream(fstream);
    ostream.writeObject(object);
    ostream.close();

或使用Kryo及其UnsafeOutput - 我总是得到一个大小约为220mb的文件。

同时在python中序列化完全相同的数据结构(使用pickle模块)会产生大小约为100mb的文件。

从我所见,BitSet类甚至声明了最佳的序列化例程(写入最少量的信息)。我唯一的猜测是额外的~100mb来自某种JVM元开销 - 但是它有点太多了吗?有没有办法减少额外的100mb?

1 个答案:

答案 0 :(得分:0)

我无法代表Python所做的事情,但Java会遇到很多麻烦,以确保您可以通过各种方式改变类定义,而不会破坏与序列化流的兼容性。例如,字段与其名称和类型一起序列化,而不依赖于类定义中的顺序。所有这些都增加了序列化协议开销。你认为BitSet最低限度序列化是正确的,所有JRE List实现都是如此。但这可能不适用于List中的任何课程。

相比之下,可以想象一个序列化协议只是直接从实例对象复制字节,并要求类在序列化和反序列化之间根本不会改变;或者序列化类型而不是名称,例如,与Java为实现其设计目标所做的相比,所有这些都可以节省空间。