我有一个解决方案,我需要非常快速地将对象读入内存,但是二进制流可能会缓存在内存中压缩以节省磁盘 io 上的时间。
我已经修改了不同的解决方案,显然 XmlTextWriter 和 XmlTextReader 不是那么好,内置的二进制序列化也不是。Protobuf-net 非常好,但还是有点太慢了。以下是一些统计数据:
文件大小 XML:217 kb
文件大小二进制:87 kb
压缩二进制:26 KB
压缩的 XML:26 KB
使用 XML (XmlTextReader) 反序列化:8.4 sek
使用二进制反序列化(Protobuf-net):6.2 sek
使用 Binary wo string.interning (Protobuf-net) 反序列化:5.2 sek
使用内存中的二进制反序列化:5.9 Sek
将二进制文件解压到内存的时间:1.8 sek
使用 Xml (XmlTextWriter) 序列化:11 sek
使用二进制序列化(Protobuf):4 sek
使用二进制长度前缀序列化(Protobuf-net):3.8 sek
这让我想到,似乎(如果我错了,请纠正我)反序列化的主要罪魁祸首是实际的字节转换而不是 IO。如果是这样,那么它应该是使用新的并行扩展的候选者。
由于我在二进制 IO 方面有点新手,但在我投入时间解决之前,我会很感激一些输入:)
为简单起见,假设我们要反序列化一个没有可选字段的对象列表。我的第一个想法是简单地存储每个长度前缀。将每个的 byte[] 读入 byte[] 列表并使用 PLINQ 进行 byte[] -> 对象反序列化。
但是,使用这种方法,我仍然需要单线程读取 byte[],所以也许可以将整个二进制流读入内存(顺便说一句,二进制文件有多大?)并在二进制文件的开头存储如何有许多对象,每个对象的长度和偏移量。然后我应该能够创建 ArraySegments 或其他东西并并行进行分块。
那你们怎么看,可行吗?