c# – 快速序列化/反序列化结构

前端之家收集整理的这篇文章主要介绍了c# – 快速序列化/反序列化结构前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我只是简单的对象结构中只包含结构体的地理数据,我的所有字段都是有价值的类型.
public struct Child
{
   readonly float X;
   readonly float Y;
   readonly int myField;
}

public struct Parent
{
   readonly int id;
   readonly int field1;
   readonly int field2;
   readonly Child[] children;
}

父母[] – 的小部分数据很好地被分块.每个数组包含几千个父实例.我有太多的数据保留所有的内存,所以我需要交换这些块到磁盘来回. (一个文件将产生约2-300KB).

将Parent []序列化/反序列化到dumpint到磁盘的一个字节[]并读回来是最有效的方式?关于速度,我特别对快速反序列化感兴趣,写速度并不那么关键.

简单的BinarySerializer会好吗?
还是应该用StructLayout (see accepted answer)?我不知道这是否适用于Parent.children的数组字段.

更新:对注释的响应 – 是的,对象是不可变的(代码更新),实际上,子字段不是值类型. 300KB的声音听起来不多,但是我有这样的数十万个文件,所以速度很重要.

解决方法

BinarySerializer是一个非常通用的串行器.它不会像自定义实现一样执行.

幸运的是,您的数据仅由结构体组成.这意味着您将能够修复Child的structlayout,只需使用从磁盘读取的字节[],使用不安全的代码对子数组进行位复制.

对于父母来说,这不是那么容易,因为你需要分开对待孩子.我建议您使用不安全的代码从您读取的字节[]中复制可复制的字段,并单独反序列化子对象.

您是否考虑使用内存映射文件将所有子项映射到内存?然后,您可以重新使用操作系统缓存设施,而不是处理读取和写入.

零拷贝反序列化一个孩子[]看起来像这样:

byte[] bytes = GetFromDisk();
fixed (byte* bytePtr = bytes) {
 Child* childPtr = (Child*)bytePtr;
 //now treat the childPtr as an array:
 var x123 = childPtr[123].X;

 //if we need a real array that can be passed around,we need to copy:
 var childArray = new Child[GetLengthOfDeserializedData()];
 for (i = [0..length]) {
  childArray[i] = childPtr[i];
 }
}

猜你在找的C#相关文章