首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并行二进制DeSerialization?

并行二进制DeSerialization?
EN

Stack Overflow用户
提问于 2009-12-20 15:20:19
回答 4查看 2.2K关注 0票数 4

我有一个解决方案,其中我需要非常快速地将对象读取到内存中,但是二进制流可能被压缩缓存在内存中,以节省磁盘io上的时间。

我已经修补了不同的解决方案,显然XmlTextWriter和XmlTextReader不是很好,内置的二进制序列化也不是。Protobuf-net很好,但还是有点慢。以下是一些统计数据:

文件大小XML: 217kb

文件大小二进制:87kb

压缩二进制:26KB

压缩XML: 26KB

使用XML反序列化(XmlTextReader):8.4SEK

使用二进制进行反序列化(Protobuf-net):6.2 sek

使用二进制wo string.interning反序列化(Protobuf-net):5.2SEK

使用内存中的二进制文件进行反序列化: 5.9 Sek

将二进制文件解压缩到内存的时间: 1.8瑞典克朗

使用可扩展标记语言序列化(XmlTextWriter):11SEK

使用二进制序列化(Protobuf):4 sek

使用二进制长度前缀序列化(Protobuf-net):3.8 sek

这让我思考,似乎(如果我错了,请纠正我)反序列化的主要罪魁祸首是实际的字节转换,而不是IO。如果是这样的话,它应该是使用新的并行扩展的候选者。

因为我是一个二进制IO的新手,所以在我花时间解决这个问题之前,我会很感谢你的一些建议:)

为了简单起见,假设我们想反序列化一个没有可选字段的对象列表。我的第一个想法是简单地用一个长度前缀来存储每个。将每个对象的byte[]读取到byte[]列表中,并使用PLINQ执行byte[] ->对象反序列化。

然而,使用这种方法,我仍然需要单线程读取byte[],所以也许可以将整个二进制流读取到内存中(对于这种btw来说,多大的二进制文件是可行的?)在二进制文件的开头存储有多少个对象,以及它们的长度和偏移量。然后,我应该能够只创建ArraySegments或其他东西,并以并行方式进行分块。

你们怎么看,这是可行的吗?

EN

回答 4

Stack Overflow用户

发布于 2009-12-23 18:48:10

我经常做这样的事情,没有什么比使用BinaryReader读取内容更好的了。据我所知,没有比使用BinaryReader.ReadInt32读取32位整数更快的方法了。

您可能还会发现,将其并行化并重新连接起来的开销太大了。如果你真的想走并行路线,我建议使用多线程来读入多个文件,而不是使用多线程来读取多个块中的一个文件。

您还可以调整块大小,使其与磁盘块大小相匹配,但应用程序和磁盘之间存在太多抽象级别,这可能会浪费时间。

票数 2
EN

Stack Overflow用户

发布于 2009-12-22 21:29:34

二进制文件可以由多个线程同时读取。为此,必须使用适当的访问/共享修饰符打开它。然后每个线程都可以在该文件中获得自己的偏移量和长度。因此,并行读取不是问题。

让我们假设您将坚持使用简单的二进制格式:每个对象都以其长度作为前缀。知道您可以“滚动”文件,并知道放置反序列化线程的偏移量。

反序列化算法可以看起来像这样: 1)分析文件(将其分成几个相对较大的块,块边界应与对象边界一致) 2)产生必要数量的反序列化线程,并用适当的偏移和长度“指示”它们读取3)将所有反序列化线程的结果组合到一个列表中

票数 1
EN

Stack Overflow用户

发布于 2009-12-23 17:52:58

让我开始思考,似乎(如果我错了,请纠正我)反序列化的罪魁祸首是实际的字节转换,而不是IO。

不要假设时间都花在哪里了,给自己找个分析器,找出答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1935109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档