网络上的 C# 列表与字节数组效率

Posted

技术标签:

【中文标题】网络上的 C# 列表与字节数组效率【英文标题】:C# list vs byte array efficiency over network 【发布时间】:2020-06-23 11:53:06 【问题描述】:

好的,所以我正在尝试使用 c# 在 unity3d 中使用自建网络代码制作多人游戏,

问题是因为我使用的是原始 tcp,所以我需要将所有内容转换为字节 [],但我厌倦了使用 Array.Copy。因为我保留了通过网络发送的每条消息的几个字节作为一种消息标识符,我可以使用它来解释我收到的数据。

所以我的问题是,为了使这段代码对我自己更友好,使用字节列表而不是字节数组是一个糟糕的主意,一旦我准备好要发送的消息,我就可以在该列表上调用 .ToArray?

这会影响性能吗?

【问题讨论】:

网络效率不依赖于代码中的实现;如果您担心网络效率或速度,您可能需要考虑 udp 我不是在这里谈论网络的效率。我更担心使用列表而不是使用 array.copy 函数会影响本地性能 【参考方案1】:

作为处理套接字时的一般规则:您通常应该使用 oversized 数组(ArrayPool<byte>.Shared 在这里很有用),然后使用接受 @ 的 Send 重载987654324@(偏移量+计数)或ArraySegment<byte> - 这样您就不会经常重新复制内容,并且可以重复使用缓冲区。但是,坦率地说:您也可以查看"pipelines";这是 Kestrel 使用的新 IO API,它为您处理所有缓冲区管理,因此您不必这样做。在核心框架中,管道目前主要以服务器为中心,但希望在 .NET 5 中作为“Bedrock”的一部分进行改进 - 但是,客户端管道包装器在 Pipelines.Sockets.Unofficial(在 NuGet 上)中可用。

明确地说:不,在List<byte> 上不断调用ToArray()不是使缓冲区更方便的好方法;这可能会起作用,但可能会导致 GC 停顿,而且它在您的套接字代码中是不必要的开销。

【讨论】:

好吧,我会看看你建议的一些东西。谢谢你的建议。

以上是关于网络上的 C# 列表与字节数组效率的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中组合两个或多个字节数组的最佳方法

用于 ScintillaNET 的字节数组到文本

C# 字符串与字节数组相互转换

将 C# char 数组传递给 C++ 与字节数组不同

C#里分割字符串和字符串转换为网络发送字节数组的方法

由字节/短而不是整数组成的 Java 数组的内存效率更高吗?