上篇文章中我们实现了紧密型数据结构序列化的方法
序列化的方法如下:
if (obj is bool)
{
buff.AddData(BitConverter.GetBytes((bool)obj), sizeof(bool));
}
我们注意到,每次使用BitConverter.GetBytes都会产生一个额外的byte[]数组
同时obj is bool 进行动态类型判断也需要时间,所以还有优化的空间
提高时间效率,可以使用unsafe关键字,用指针来解决上述问题:
Serialize.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NetWork.NetWork
{
unsafe public class Serialization
{
public virtual void Serializable(ref Dynamical buff)
{
// 子类继承
}
public virtual void DeSerializable(ref byte *buff, ref int size)
{
// 子类继承
}
public void SerializableBase(ref Dynamical buff, bool value)
{
byte* b = (byte*)&value;
buff.AddData(b, sizeof(bool));
}
public void SerializableBase(ref Dynamical buff, int value)
{
byte* b = (byte*)&value;
buff.AddData(b, sizeof(int));
}
public void SerializableBase(ref Dynamical buff, float value)
{
byte* b = (byte*)&value;
buff.AddData(b, sizeof(float));
}
public void SerializableBase(ref Dynamical buff, double value)
{
byte* b = (byte*)&value;
buff.AddData(b, sizeof(double));
}
public void SerializableBase(ref Dynamical buff, char value)
{
byte* b = (byte*)&value;
buff.AddData(b, sizeof(char));
}
public void DeSerializableBase(ref byte* buff, ref int size, out bool b)
{
b = false;
int len = sizeof(bool);
if (size - len > 0)
{
bool *t = (bool *)buff;
b = *t;
}
size -= len;
}
public void DeSerializableBase(ref byte* buff, ref int size, out int b)
{
b = 0;
int len = sizeof(bool);
if (size - len > 0)
{
int* t = (int*)buff;
b = *t;
}
size -= len;
}
public void DeSerializableBase(ref byte* buff, ref int size, out double b)
{
b = 0.0;
int len = sizeof(double);
if (size - len > 0)
{
double* t = (double*)buff;
b = *t;
}
size -= len;
}
public void DeSerializableBase(ref byte* buff, ref int size, out float b)
{
b = 0.0f;
int len = sizeof(float);
if (size - len > 0)
{
float* t = (float*)buff;
b = *t;
}
size -= len;
}
public void DeSerializableBase(ref byte* buff, ref int size, out char b)
{
b = '0';
int len = sizeof(char);
if (size - len > 0)
{
char* t = (char*)buff;
b = *t;
}
size -= len;
}
}
unsafe public class ListNode : Serialization
{
public int node_id;
public override void Serializable(ref Dynamical buff)
{
SerializableBase(ref buff, node_id);
}
public override void DeSerializable(ref byte* buff, ref int size)
{
DeSerializableBase(ref buff, ref size, out node_id);
}
}
unsafe public class ChildClass : Serialization
{
public int id;
public char c;
public double d;
public List<ListNode> list;
public override void Serializable(ref Dynamical buff)
{
SerializableBase(ref buff, id);
SerializableBase(ref buff, c);
SerializableBase(ref buff, d);
int count = list.Count;
SerializableBase(ref buff, count);
for (int i = 0; i < count; i++)
{
list[i].Serializable(ref buff);
}
}
public override void DeSerializable(ref byte* buff, ref int size)
{
DeSerializableBase(ref buff, ref size, out id);
DeSerializableBase(ref buff, ref size, out c);
DeSerializableBase(ref buff, ref size, out d);
int count = 0;
DeSerializableBase(ref buff, ref size, out count);
for (int i = 0; i < count; i++)
{
ListNode node = new ListNode();
node.DeSerializable(ref buff, ref size);
}
}
}
}
Dynamical.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NetWork.NetWork
{
unsafe public class Dynamical
{
public Dynamical()
{
buff = new List<byte>(10);
cur_len = 0;
max_len = 10;
}
public int GetSize()
{
return cur_len;
}
public void AddData(byte* data, int size)
{
for (int i = cur_len; i < cur_len + size; i++)
{
if (i < max_len)
{
buff[i] = data[i - cur_len];
}
else
{
buff.Add(data[i - cur_len]);
}
}
cur_len += size;
max_len += buff.Count;
}
public void RemoveData(int start, int size)
{
if (start < 0 || size < 0 || start +size > cur_len)
{
return;
}
for (int i = 0; i < cur_len - start - size; i++)
{
buff[i + start] = buff[start + size + i];
}
cur_len -= size;
}
public void GetData(ref byte[] data, int start, int size)
{
if (start < 0 || size <= 0 || start + size > cur_len)
{
return;
}
byte[] tmp = new byte[size];
for (int i = 0; i < size; i ++)
{
tmp[i] = buff[i + start];
}
data = tmp;
}
List<byte> buff;
int cur_len;
int max_len;
}
}
test.cs
using NetWork.NetWork;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NetWork
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
unsafe private void Form1_Load(object sender, EventArgs e)
{
ChildClass c = new ChildClass();
Dynamical dynamical = new Dynamical();
c.Serializable(ref dynamical);
byte[] buff = null;
dynamical.GetData(ref buff, 0, dynamical.GetSize());
ChildClass c1 = new ChildClass();
fixed (byte* p = &buff[0])
{
int size = buff.Count();
byte* p1 = p;
c1.DeSerializable(ref p1, ref size);
}
}
}
}
使用指针可以减少拷贝,加快速度,
但是会造成不安全,
好像被众人所鄙视
不管了
正所谓:只堪一撕即破