c#序列化(紧密型数据结构)(二)

   上篇文章中我们实现了紧密型数据结构序列化的方法

    序列化的方法如下:

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);
            }
        }
    }
}

使用指针可以减少拷贝,加快速度,

但是会造成不安全,

好像被众人所鄙视

不管了

正所谓:只堪一撕即破

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值