我有一个解决方案,需要快速地将对象读入内存,但是二进制流可能会在内存中缓存压缩以节省磁盘IO时间。
我已经尝试了不同的解决方案,显然XmlTextWriter和XmlTextReader并不好用,内置的二进制序列化也不行。Protobuf-net非常出色,但仍然有点慢。以下是一些统计数据:
文件大小XML:217 kb
文件大小二进制:87 kb
压缩二进制:26 KB
压缩XML:26 KB
使用XML进行反序列化(XmlTextReader):8.4秒
使用二进制进行反序列化(Protobuf-net):6.2秒
使用未采用字符串内部化的二进制进行反序列化(Protobuf-net):5.2秒
从内存中反序列化二进制:5.9秒
将二进制文件解压到内存所需的时间:1.8秒
使用XML进行序列化(XmlTextWriter):11秒
使用二进制进行序列化(Protobuf):4秒
使用带长度前缀的二进制进行序列化(Protobuf-net):3.8秒
这让我想到,看起来(如果我错了,请纠正我),反序列化的主要罪魁祸首是实际的字节转换而不是IO。如果是这样的话,那么它应该是使用新的Parallel扩展的候选者。
由于我在二进制IO方面有点新手,所以在投入时间之前,我希望得到一些输入:)
为了简单起见,假设我们想反序列化一个没有可选字段的对象列表。我的第一个想法是简单地使用每个长度前缀存储每个对象。将每个字节数组读入字节数组列表中,并使用PLINQ进行字节数组 -> 对象反序列化。
然而,使用该方法仍然需要单线程读取字节数组,因此也许可以将整个二进制流读入内存(那么多大的二进制文件适合这样做?),并在二进制文件开头存储有多少个对象以及它们的长度和偏移量。然后我应该能够只创建ArraySegments或类似的东西,并且也可以在并行中进行分块。
那么你们觉得,这可行吗?
我已经尝试了不同的解决方案,显然XmlTextWriter和XmlTextReader并不好用,内置的二进制序列化也不行。Protobuf-net非常出色,但仍然有点慢。以下是一些统计数据:
文件大小XML:217 kb
文件大小二进制:87 kb
压缩二进制:26 KB
压缩XML:26 KB
使用XML进行反序列化(XmlTextReader):8.4秒
使用二进制进行反序列化(Protobuf-net):6.2秒
使用未采用字符串内部化的二进制进行反序列化(Protobuf-net):5.2秒
从内存中反序列化二进制:5.9秒
将二进制文件解压到内存所需的时间:1.8秒
使用XML进行序列化(XmlTextWriter):11秒
使用二进制进行序列化(Protobuf):4秒
使用带长度前缀的二进制进行序列化(Protobuf-net):3.8秒
这让我想到,看起来(如果我错了,请纠正我),反序列化的主要罪魁祸首是实际的字节转换而不是IO。如果是这样的话,那么它应该是使用新的Parallel扩展的候选者。
由于我在二进制IO方面有点新手,所以在投入时间之前,我希望得到一些输入:)
为了简单起见,假设我们想反序列化一个没有可选字段的对象列表。我的第一个想法是简单地使用每个长度前缀存储每个对象。将每个字节数组读入字节数组列表中,并使用PLINQ进行字节数组 -> 对象反序列化。
然而,使用该方法仍然需要单线程读取字节数组,因此也许可以将整个二进制流读入内存(那么多大的二进制文件适合这样做?),并在二进制文件开头存储有多少个对象以及它们的长度和偏移量。然后我应该能够只创建ArraySegments或类似的东西,并且也可以在并行中进行分块。
那么你们觉得,这可行吗?