c#改进二进制序列化

时间:2016-04-07 07:40:28

标签: c# binary unsafe bitconverter

我目前正在开发一个基于其他代码生成代码的项目。基本上使用编程语言本身作为DSL。

其中一个生成器目标是binary DataContract serializer,以及为以下类生成的ToBytes

[DataContract]
public partial class Root
{
    [DataMember]
    public int Number { get; set; }

    [DataMember]
    public Partial[] Partials { get; set; }

    [DataMember]
    public IList<ulong> Numbers { get; set; }
}

成为这个:

public int Size
{
    get 
    { 
        var size = 8;
        // Add size for collections and strings
        size += Partials.Sum(entry => entry.Size);
        size += Numbers.Count * 8;

        return size;              
    }
}
public byte[] ToBytes()
{
    var index = 0;
    var bytes = new byte[Size];

    return ToBytes(bytes, ref index);
}
public byte[] ToBytes(byte[] bytes, ref int index)
{
    // Convert Number
    Buffer.BlockCopy(BitConverter.GetBytes(Number), 0, bytes, index, 4);;
    index += 4;
    // Convert Partials
    // Two bytes length information for each dimension
    Buffer.BlockCopy(BitConverter.GetBytes((ushort)(Partials == null ? 0 : Partials.Length)), 0, bytes, index, 2);
    index += 2;
    foreach(var value in Partials ?? Enumerable.Empty<Partial>())
    {
        value.ToBytes(bytes, ref index);
    }
    // Convert Numbers
    // Two bytes length information for each dimension
    Buffer.BlockCopy(BitConverter.GetBytes((ushort)(Numbers == null ? 0 : Numbers.Count)), 0, bytes, index, 2);
    index += 2;
    foreach(var value in Numbers ?? Enumerable.Empty<ulong>())
    {
        Buffer.BlockCopy(BitConverter.GetBytes(value), 0, bytes, index, 8);;
        index += 8;
    }
    return bytes;
}

现在即使这很艰难,这真的很快我正在寻找一种方法来加速Buffer.BlockCopy(BitConverter.GetBytes的所有用途。为每次转换创建一个新的小byte[]似乎浪费资源,然后在我已经拥有byte[]和位置时复制它。

如何最好地改进代码?

更新:基于@adrianm注释,我将用for循环替换foreach数组,并在if语句中包含nullable类型。不需要使用another thread中的结构。我宁愿使用类和[DataContract]属性。另外,对于Linux合规性,我不能使用WinApi。

Update2:添加了其余生成的代码。感谢评论未来版本将包括

if (index + Size > bytes.Length)
    // Some error handling

1 个答案:

答案 0 :(得分:0)

所以我看到了BitConverter的实现以及他们使用unsafe和指针来创建byte[]。我想在生成的代码中使用它,如:

*byte pointer = bytes;
*((int*)pointer + pos) = Number;
pos += 4;

但在这种情况下,这将是一个不安全的方法,我不知道这将对那里更多的托管代码做什么。

相关问题