C#将变量复制到缓冲区而不创建垃圾?

C#将变量复制到缓冲区而不创建垃圾?,c#,.net,buffer,C#,.net,Buffer,在C#.Net(3.5及以上版本)中,是否可以将变量复制到byte[]缓冲区,而不在过程中创建任何垃圾 例如: int variableToCopy = 9861; byte[] buffer = new byte[1024]; byte[] bytes = BitConverter.GetBytes(variableToCopy); Buffer.BlockCopy(bytes, 0, buffer, 0, 4); float anotherVariableToCopy = 6743897

在C#.Net(3.5及以上版本)中,是否可以将变量复制到byte[]缓冲区,而不在过程中创建任何垃圾

例如:

int variableToCopy = 9861;

byte[] buffer = new byte[1024];
byte[] bytes = BitConverter.GetBytes(variableToCopy);
Buffer.BlockCopy(bytes, 0, buffer, 0, 4);

float anotherVariableToCopy = 6743897.6377f;
bytes = BitConverter.GetBytes(anotherVariableToCopy);
Buffer.BlockCopy(bytes, 0, buffer, 4, sizeof(float));

...
创建字节[]字节中间对象,该对象将成为垃圾(假定不再保留引用)

我想知道是否可以使用位运算符将变量直接复制到缓冲区中,而不创建中间字节[]?

为什么不能执行以下操作:

byte[] buffer = BitConverter.GetBytes(variableToCopy);
请注意,这里的数组不是原始Int32的间接存储,它实际上是一个副本

您可能担心示例中的
字节
等同于:

unsafe
{
    byte* bytes = (byte*) &variableToCopy;
}
。。但我向你保证,事实并非如此;它是源Int32中字节的逐字节副本

编辑

根据您的编辑,我认为您需要这样的内容(需要不安全的上下文):

public不安全静态void CopyBytes(int值,byte[]目标,int偏移量)
{
如果(目标==null)
抛出新的ArgumentNullException(“目标”);
if(偏移量<0 | |(偏移量+sizeof(int)>destination.Length))
抛出新ArgumentOutOfRangeException(“偏移量”);
固定(字节*ptrToStart=目的地)
{
*(int*)(ptrToStart+offset)=值;
}
}

使用指针是最好、最快的方法: 您可以使用任意数量的变量执行此操作,没有浪费内存,fixed语句有一点开销,但它太小了

        int v1 = 123;
        float v2 = 253F;
        byte[] buffer = new byte[1024];
        fixed (byte* pbuffer = buffer)
        {
            //v1 is stored on the first 4 bytes of the buffer:
            byte* scan = pbuffer;
            *(int*)(scan) = v1;
            scan += 4; //4 bytes per int

            //v2 is stored on the second 4 bytes of the buffer:
            *(float*)(scan) = v2;
            scan += 4; //4 bytes per float
        }

因为与我的示例不同,我的缓冲区需要保存许多变量——我将更新我的问题是的,这是可能的,但在我看来,您似乎在过早地进行优化。在方法调用中创建的垃圾(如小字节数组等)都是Gen 0对象,很可能在几毫秒内或更短时间内收集。CLR中的临时对象分配和收集非常有效。第0代对象是什么?(出于您的担忧-我不认为优化还为时过早-我不确定自己听起来是什么样子-我正在编写一个供手机使用的库,并使用缓冲区100,可能每秒使用数千次-GC关注的是此类资源受限的设备)。这是一个问题,但直到你测量它。如果你没有测量它,你就不知道。即使是最好的工程师也常常对测量后的真正性能瓶颈感到惊讶。Gen0是“一代”GC用于跟踪最新创建的对象。大多数工作负载都有分配、使用大量对象然后超出范围的模式。在执行GC而不是整个堆时,查看这组受限制的对象是有意义的。.Net这样做,以及GC分配和收集对象的速度这是一个惊人的模式。请看:也许有什么值得一提的:注意所有固定(固定)对象。它们可能会导致堆碎片,最终可能会使用更多内存。
        int v1 = 123;
        float v2 = 253F;
        byte[] buffer = new byte[1024];
        fixed (byte* pbuffer = buffer)
        {
            //v1 is stored on the first 4 bytes of the buffer:
            byte* scan = pbuffer;
            *(int*)(scan) = v1;
            scan += 4; //4 bytes per int

            //v2 is stored on the second 4 bytes of the buffer:
            *(float*)(scan) = v2;
            scan += 4; //4 bytes per float
        }