【发布时间】:2009-12-20 07:20:18
【问题描述】:
我有一个解决方案,我需要非常快速地将对象读入内存,但是二进制流可能会在内存中缓存压缩以节省磁盘 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 或其他东西并并行进行分块。
那你们怎么看,可行吗?
【问题讨论】:
-
对不起,有些问题我并没有真正得到明确的答案,但一开始我根本没有意识到要设置它。虽然吸取了教训,但感谢您指出这一点。不过,您似乎无法为旧问题设置答案,还是我遗漏了什么?
-
为了支持 Alon,您发布的那个 java 字符串比较问题有一些经过深思熟虑的答案...
-
同意,如何设置正确答案?
-
没关系,我很笨,没想到你可以点击 v 符号 :)
-
是“sek”秒吗?如果是这样,似乎其他地方出现了可怕的错误。我们在几分之一秒内反序列化数十 MB 大小的文档...
标签: c# serialization binary-data