如果去除一段 C# 代码中的 unsafe fixed

下面是 EnyimMemcachedCore 中的一段代码,由于进行了指针操作,所以用到了 unsafe fixed ,请问有没有办法可以去掉 unsafe fixed

public unsafe IList<ArraySegment<byte>> CreateBuffer(IList<ArraySegment<byte>> appendTo)
{
    // key size 
    byte[] keyData = BinaryConverter.EncodeKey(this.Key);
    int keyLength = keyData == null ? 0 : keyData.Length;

    if (keyLength > 0xffff) throw new InvalidOperationException("KeyTooLong");

    // extra size
    ArraySegment<byte> extras = this.Extra;
    int extraLength = extras.Array == null ? 0 : extras.Count;
    if (extraLength > 0xff) throw new InvalidOperationException("ExtraTooLong");

    // body size
    ArraySegment<byte> body = this.Data;
    int bodyLength = body.Array == null ? 0 : body.Count;

    // total payload size
    int totalLength = extraLength + keyLength + bodyLength;

    //build the header
    byte[] header = new byte[24];

    fixed (byte* buffer = header)
    {
        buffer[0x00] = 0x80; // magic
        buffer[0x01] = this.Operation;

        // key length
        buffer[0x02] = (byte)(keyLength >> 8);
        buffer[0x03] = (byte)(keyLength & 255);

        // extra length
        buffer[0x04] = (byte)(extraLength);

        // 5 -- data type, 0 (RAW)
        // 6,7 -- reserved, always 0

        buffer[0x06] = (byte)(this.Reserved >> 8);
        buffer[0x07] = (byte)(this.Reserved & 255);

        // body length
        buffer[0x08] = (byte)(totalLength >> 24);
        buffer[0x09] = (byte)(totalLength >> 16);
        buffer[0x0a] = (byte)(totalLength >> 8);
        buffer[0x0b] = (byte)(totalLength & 255);

        buffer[0x0c] = (byte)(this.CorrelationId >> 24);
        buffer[0x0d] = (byte)(this.CorrelationId >> 16);
        buffer[0x0e] = (byte)(this.CorrelationId >> 8);
        buffer[0x0f] = (byte)(this.CorrelationId & 255);

        ulong cas = this.Cas;
        // CAS
        if (cas > 0)
        {
            // skip this if no cas is specfied
            buffer[0x10] = (byte)(cas >> 56);
            buffer[0x11] = (byte)(cas >> 48);
            buffer[0x12] = (byte)(cas >> 40);
            buffer[0x13] = (byte)(cas >> 32);
            buffer[0x14] = (byte)(cas >> 24);
            buffer[0x15] = (byte)(cas >> 16);
            buffer[0x16] = (byte)(cas >> 8);
            buffer[0x17] = (byte)(cas & 255);
        }
    }

    var retval = appendTo ?? new List<ArraySegment<byte>>(4);

    retval.Add(new ArraySegment<byte>(header));

    if (extraLength > 0) retval.Add(extras);

    // NOTE key must be already encoded and should not contain any invalid characters which are not allowed by the protocol
    if (keyLength > 0) retval.Add(new ArraySegment<byte>(keyData));
    if (bodyLength > 0) retval.Add(body);

    return retval;
}
Cats萌萌
浏览 700回答 9
9回答

Smart猫小萌

后来想到,这不正是 Span<T> 与 stackalloc 的用武之地吗,于是进行了这样的修改: 1)去掉 unsafe 2)将 fixed (byte* buffer = header) 改为 Span<byte> header = stackalloc byte[24]; 3)将 buffer 变量名都改为 header 4)将 retval.Add(new ArraySegment<byte>(header)); 改为 `retval.Add(new ArraySegment<byte>(header.ToArray())); 这样修改后,持续集成通过

汪汪一只猫

也没其他操作,直接去掉就行了。

噜噜哒

@dudu: 去掉 buffer,直接给header赋值操作就行了。无非慢点点而已。

POPMUISE

@花飘水流兮: 这地方性能要求很高

摇曳的蔷薇

@花飘水流兮: 这个提问本来就是为了解决如何兼得鱼和熊掌

慕运维8079593

为什么要去掉呢。必要的时候 指针操作的高性能是普通的操作难以企及的。

暮色呼如

去掉的只是是 unsafe fixed ,没有去掉指针
打开App,查看更多内容
随时随地看视频慕课网APP