我目前正在开发一个基于其他代码生成代码的项目。基本上使用编程语言本身作为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
答案 0 :(得分:0)
所以我看到了BitConverter的实现以及他们使用unsafe和指针来创建byte[]
。我想在生成的代码中使用它,如:
*byte pointer = bytes;
*((int*)pointer + pos) = Number;
pos += 4;
但在这种情况下,这将是一个不安全的方法,我不知道这将对那里更多的托管代码做什么。