为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
Cats萌萌 2018-12-06 13:04:17
下面是 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; }
查看完整描述

9 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

后来想到,这不正是 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()));

这样修改后,持续集成通过

查看完整回答
反对 回复 2018-12-24
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

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

查看完整回答
反对 回复 2018-12-24
?
噜噜哒

TA贡献1784条经验 获得超7个赞

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

查看完整回答
反对 回复 2018-12-24
?
POPMUISE

TA贡献1765条经验 获得超5个赞

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

查看完整回答
反对 回复 2018-12-24
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

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

查看完整回答
反对 回复 2018-12-24
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

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

查看完整回答
反对 回复 2018-12-24
?
暮色呼如

TA贡献1853条经验 获得超9个赞

去掉的只是是 unsafe fixed ,没有去掉指针

查看完整回答
反对 回复 2018-12-24
  • 9 回答
  • 0 关注
  • 699 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信