c# – 并行二进制去磁化?
作者:互联网
我有一个解决方案,我需要非常快速地将对象读入内存,但二进制流可能会被缓存压缩在内存中以节省磁盘上的时间.
我使用不同的解决方案,显然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.如果是那样的话那么它应该是使用新的Parallel扩展的候选者.
因为我在二进制IO方面有点新手,所以在我提交解决方案之前我会欣赏一些输入:)
为简单起见,假设我们要反序列化没有可选字段的对象列表.我的第一个想法是简单地存储每个长度前缀.将每个字节[]读入byte []列表,并使用PLINQ进行字节[] – >对象反序列化.
然而,使用该方法我仍然需要单线读取byte [],所以也许可以将整个二进制流读入内存而不是(对于那个btw有多大的二进制文件?)并且在二进制文件的开头而不是存储如何这里有许多物体,它们的长度和偏移量各不相同.然后我应该能够创建ArraySegments或其他东西,并在paralllel中进行分块.
那你觉得怎么样,这样可行吗?
解决方法:
我做了很多这样的事情,没有什么能比使用BinaryReader读取内容更多.据我所知,没有比使用BinaryReader.ReadInt32读取32位整数更快的方法.
您可能还会发现使其并行并重新连接在一起的开销太大.如果你真的想要并行路由,我会建议使用多个线程来读取多个文件,而不是多个线程来读取多个块中的一个文件.
您还可以使用块大小来匹配磁盘块大小,但是在应用程序和磁盘之间存在很多级别的抽象,这可能会浪费时间.
标签:c,serialization,binary-data 来源: https://codeday.me/bug/20190701/1343940.html