高效的C#字节队列,用于解析二进制消息包的字节流

时间:2010-07-18 14:23:42

标签: c# data-structures queue buffer

我正在尝试将我通常实现的内容替换为循环缓冲区+。队列的功能是缓冲传入的字节(例如,来自串口或其他一些数据流),而解析器检查队列中的字节并检测和提取消息包。

标准:

  • 可以成长(即不固定大小)
  •   

    =一次可以排队1个字节

  •   

    = 1个字节一次可以出列

  • 高效

我很想使用

System.Collections.Generic.Queue<byte>

...但我不确定这是否是最有效的类型。有什么建议吗?

有没有更聪明的方法来做我想做的事情? (例如,有趣的建议here

感谢您的建议&amp;输入

Prembo。

5 个答案:

答案 0 :(得分:3)

好吧,Queue<byte>在内存方面效率很高。它基本上是幕后的byte[]。如果您想要一次出列或排队整个块,可能会有点尴尬。每个操作应该为单个字节分摊O(1),导致O(n)将大小为n的块排队或出列...但缩放因子将高于(比如)缓冲区块副本。

答案 1 :(得分:2)

Queue<byte>byte[]支持,但如果使用Array.Copy复制到底层缓冲区或从底层缓冲区复制,而不是循环使用Enqueue / Dequeue方法,则会看到更好的性能。所以,就个人而言,如果Queue<byte>没有为您提供所需的性能,那么您可以实现自己的队列类,该类提供QueueMultiple和DequeueMultiple方法。

答案 2 :(得分:2)

根据接收传入字节的方式以及解析器如何检查它们,您可能会考虑Queue<byte[]>

答案 3 :(得分:2)

我知道我没有帮助,但你可以自己写一个。
理论部分:
队列应该在byte[]和2个索引中,1表示头部,1表示尾部

0                                                    n
|----------------------------------------------------|
               |                        |
              head                     tail

每当您需要添加k个字节时,您将向左移动k个单位,并将新空间创建数据放入其中。

0                                                    n
|-------------------------------new data-------------|
               |                |       |
              head         new tail  old tail

每当您需要弹出k字节时,您会移动头部k单位,并从丢失的空间中获取数据。

0                                                    n
|-------new data-------------------------------------|
       |       |                        |
   new head   head                     tail

如果头部和尾部发生碰撞,您需要将容器的大小加倍并将每一半复制到新容器。

请注意:如果您添加1234然后弹出2个字母,您将获得34

(我不知道是否应将此帖标记为社区维基)

答案 4 :(得分:1)

我刚才写过的 an efficient implementation 缓冲区:

  • 可调整大小:允许排队数据而不是抛出缓冲区溢出异常;
  • 高效:使用单个缓冲区和Buffer.Copy操作来排队/出列数据