C# 正在将'System.Guid'复制到'byte[]`而不分配

C# 正在将'System.Guid'复制到'byte[]`而不分配,c#,memory,optimization,C#,Memory,Optimization,我正在开发的应用程序非常关注性能,因此需要将分配降至最低,以减少GC暂停 我惊讶地发现,System.Guid没有公开任何方法将其byte[]表示复制到现有缓冲区中。唯一现有的方法是Guid.ToByteArray(),它执行新字节[]分配,否则没有它就无法获取底层字节 因此,我正在寻找一种方法,将Guid复制到一个已经存在的byte[]缓冲区,而不分配任何内存(因为Guid已经是一种值类型)。我找到的解决方案来自by的一些帮助。我并没有给出确切的解决方案,但它激励我想出了一些我认为相当优雅的东

我正在开发的应用程序非常关注性能,因此需要将分配降至最低,以减少GC暂停

我惊讶地发现,
System.Guid
没有公开任何方法将其
byte[]
表示复制到现有缓冲区中。唯一现有的方法是
Guid.ToByteArray()
,它执行
新字节[]
分配,否则没有它就无法获取底层字节


因此,我正在寻找一种方法,将
Guid
复制到一个已经存在的
byte[]
缓冲区,而不分配任何内存(因为
Guid
已经是一种值类型)。

我找到的解决方案来自by的一些帮助。我并没有给出确切的解决方案,但它激励我想出了一些我认为相当优雅的东西

注意:以下代码使用并要求使用
/unsafe
开关构建项目(并且很可能需要完全信任才能运行)

对该时间进行计时,副本的平均持续时间为1-2个刻度。对于大多数应用程序来说应该足够快


但是,如果您想获得绝对最佳的性能,一种可能性(Kevin建议)是确保
offset
参数是
long
对齐的(在8字节边界上)。我的特定用例倾向于使用内存而不是速度,但是如果速度是最重要的,那么这将是一个很好的解决方法。

如果速度是主要考虑因素,您可以通过直接使用
Guid
而不是通过
GuidBuffer
结构来节省大量时间。这是我正在使用的扩展方法

public static unsafe void Encode(this byte[] array, int offset, Guid value)
{
    if (array.Length - offset < 16) throw new ArgumentException("buffer too small");

    fixed (byte* pArray = array)
    {
        var pGuid = (long*)&value;
        var pDest = (long*)(pArray + offset);
        pDest[0] = pGuid[0];
        pDest[1] = pGuid[1];
    }
}

你真的需要
Guid
?可能只是直接创建
[dlliport(“ole32.dll”,SetLastError=true)]静态外部int-CoCreateGuid(byte[]guid)(或)?不幸的是,是的。问题不是我需要创建一个Guid,而是我已经有了一个Guid实例,我需要它进入现有的字节数组,而不需要分配中间缓冲区。注意,在gc语言中,这种分配几乎不需要任何成本(增加托儿所指针)。pinvoke甚至fixed可能不会更具扩张性,除非你在一个Op中处理一个更大的数字,否则分配不会伤害你。这是最终的垃圾收集成本。我不是100%确定,因为它已经有一段时间了,但有一些原因,我不能依靠直接使用
System.Guid
。如果这不是目前的情况,那么伟大的提示@rossipedia,如果你碰巧还记得症结所在,我会很高兴知道那是什么,即使是OBE。也就是说,ReSharper帮助我获得了上面列出的最终版本。“我不确定没有那个帮助我能做这件事。”rossipedia,顺便说一句,没有你的回答,我不可能做这件事。谢谢你。
var myGuid = Guid.NewGuid(); // however you get it
var guidBuffer = new GuidBuffer(myGuid);

var buffer = new buffer[16];
guidBuffer.CopyTo(buffer, 0);
public static unsafe void Encode(this byte[] array, int offset, Guid value)
{
    if (array.Length - offset < 16) throw new ArgumentException("buffer too small");

    fixed (byte* pArray = array)
    {
        var pGuid = (long*)&value;
        var pDest = (long*)(pArray + offset);
        pDest[0] = pGuid[0];
        pDest[1] = pGuid[1];
    }
}
var guid  = Guid.NewGuid();
var array = new byte[16];
array.Encode(0, guid);