Java 间隔树实现在序列化后占用大量文件空间

Java 间隔树实现在序列化后占用大量文件空间,java,algorithm,optimization,serialization,tree,Java,Algorithm,Optimization,Serialization,Tree,我有一个包含IPv6范围和范围所属ISP的文本文件(范围不重叠)。以下是一些示例(假)行: 2010:258:0:0:0:0:0:0;2010:258:ffff:ffff:ffff:ffff:ffff:ffff;ISP_1; 2010:260:0:0:0:0:0:0;2010:260:ffff:ffff:ffff:ffff:ffff:ffff;ISP_2; 2010:268:0:0:0:0:0:0;2010:268:ffff:ffff:ffff:ffff:ffff:ffff;ISP_3; 我已

我有一个包含IPv6范围和范围所属ISP的文本文件(范围不重叠)。以下是一些示例(假)行:

2010:258:0:0:0:0:0:0;2010:258:ffff:ffff:ffff:ffff:ffff:ffff;ISP_1;
2010:260:0:0:0:0:0:0;2010:260:ffff:ffff:ffff:ffff:ffff:ffff;ISP_2;
2010:268:0:0:0:0:0:0;2010:268:ffff:ffff:ffff:ffff:ffff:ffff;ISP_3;
我已经取得了这个文本文件,并创建了一个从它,所以我可以快速查找哪个ISP的一个特定的IP属于。间隔树中的每个节点都具有以下结构:

public class Node implements Serializable {
    Range nodeRange;

    IntervalTreeNode left;
    IntervalTreeNode right;

    UnsignedLong128 centerValue;

}
以下是
范围

public abstract class Range implements Comparable<Range>, Serializable {

    UnsignedLong128 start;
    UnsignedLong128 end;
    boolean sortAccordingToStart;
}
问题是,如果我序列化树并将其写入文件,该文件的大小远远大于原始文本文件的大小。下面是一个示例:我有一个文本文件,其中包含19860行范围行,该文本文件的大小为1.7MB。当我基于它创建间隔树并将该树写入文件时(通过Java的序列化),结果文件的大小为15.7 MB,即使它存储相同的信息。是的,树所容纳的节点数量是文本文件行数的两倍(我生成的树是平衡的),这仍然不能证明文件大小增加了这么多


那么,是什么导致了文件大小的增长,我该如何缩减它呢?

Java序列化将有很大的开销,如果您使用文本编辑器查看文件,您可能会看到这一点

由于这些范围不重叠,您可以将数据按顺序排序(比较两个范围并比较其起点或终点),然后使用二进制搜索查找匹配项。然后你只需要序列化一个结构数组。您可能会发现,如果您有一个或三个大数组,其中包含起点、终点和ISP ID,或者您可以自己读取和写入数据,那么Java序列化的开销会更小


您还可以研究readResolve()和writeReplace()

您可以实现
Externalizable
,它允许您在使用
Serializable
框架的同时自定义序列化。它相当简单,每个字段和每个方向都需要一条线
Serializable
有一些开销,因为每个字段都可能包含
null
或其类型的子类的实例,但您通常知道这是不可能发生的

我不确定,但我想,
Serializable
默认情况下使用UTF-16,这既快又简单,因为这是Java内部的功能(或者说,Java 9可以做得更好),但对于纯ASCII来说,它浪费了两倍的时间(使用UTF-8很好)。看起来你用数字代替了字符串,所以可能没用


您的
UnsignedLong128
也会浪费内存。将
Long
替换为
Long
。不知道它对序列化的数据大小有多大帮助,但可以节省大量RAM(并获得一些速度)。

如果不需要坚持序列化,还可以创建
readFile
toFile
方法来存储树。
public class UnsignedLong128 implements Comparable<UnsignedLong128>, Serializable {

    Long major;
    Long minor;
}