如何在不分配内存的情况下向单个 Span<byte> 添加零填充?

The*_*Mah 2 c# performance memory-management

我有一个方法可以转换Span<byte>int

int ConvertToInt32(Span<byte> buffer)
{
    if (buffer.Length != 4)
    {
        // add zero-padding to the buffer
    }

    return BitConverter.ToInt32(buffer);
    // or MemoryMarshal....
}
Run Code Online (Sandbox Code Playgroud)

如果输入参数 ( buffer) 长度为 4,则转换有效,但如果输入参数 ( ) 长度小于 4 个字节,则转换无效。我正在寻找一种非分配方法来执行此操作。那么如何在buffer转换前添加零填充,或者还有其他解决方案吗?

Gur*_*ron 7

您可以在堆栈上分配,stackalloc这应该比在堆上分配更便宜,并且是高性能场景中的常用方法 AFAIK:

Span<byte> buffer = stackalloc byte[3] {0,0,1};
if (buffer.Length != 4)
{
    Span<byte> interimBuffer = stackalloc byte[4];
    // ..
}
Run Code Online (Sandbox Code Playgroud)

请注意,您只需转换为具有相应大小的类型,然后转换为int

if (buffer.Length == 2)
{
    var int16 = (int)BitConverter.ToInt16(buffer);
}
Run Code Online (Sandbox Code Playgroud)

但由于分支,它的性能可能会更差。

另外,不要忘记文档中所写的计算机体系结构的字节序。

  • @JimMischel _“我想知道与静态数组相比性能如何”_ - 测试它,我建议使用 BenchmarkDotNet。在单线程处理中,它可能会更快,但通常您不希望受限于一个线程。_“您建议如何处理三个字节?”_ - 就像您现在处理每个非 4 字节情况的方式一样) (2认同)