用于解析二进制消息包的字节流的高效 C# 字节队列
我正在尝试替换我通常实现的循环缓冲区+。队列的功能是缓冲传入的字节(例如,来自串行端口或其他一些数据流),同时解析器检查队列中的字节并检测和提取消息包。
标准:
- 可以增长(即不固定大小)
- <块引用>
= 一次可以入队 1 个字节
- <块引用>
= 一次可以出列 1 个字节
- 有效地
出列我很想使用
System.Collections.Generic.Queue<byte>
...但我不确定这是否是最有效的类型。有什么建议吗?
有没有更聪明的方法来做我想做的事情? (例如,有趣的建议此处)
感谢您的建议&输入。
普雷姆博。
I'm trying to replace what I would usually implement as a circular-buffer+. The function of the queue is to buffer incoming bytes (eg. from serial port or some other stream of data), whilst a parser examines bytes in the queue and detects and extracts message packets.
Criteria:
- can grow (ie not fixed-sized)
= 1 bytes can be enqueued at a time
= 1 bytes can be dequeued at a time
- efficient
I'm tempted just to use
System.Collections.Generic.Queue<byte>
... but I'm not sure if this is the most efficient type to use. Any suggestions?
Are there any smarter ways of doing what I'm trying to do? (Eg. Interesting suggestions here)
Thanks for your suggestions & input.
Prembo.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
嗯,
Queue
在内存方面会非常高效。它基本上是幕后的一个byte[]
。不过,如果您想一次将整个块出队或入队,那么使用起来可能会有点尴尬。对于单个字节,每个操作应分摊为 O(1),导致 O(n) 入队或出队大小为 n 的块...但缩放因子将高于(例如)缓冲区块副本。Well,
Queue<byte>
will be efficient in terms of memory. It will basically be abyte[]
behind the scenes. It may be slightly awkward to work with if you want to dequeue or enqueue whole chunks at a time though. Each operation should be amortized O(1) for a single byte, leading to O(n) to enqueue or dequeue a chunk of size n... but the scaling factor will be higher than (say) a buffer block copy.Queue
由byte[]
支持,但如果使用Array.Copy
复制到底层缓冲区或从底层缓冲区复制,您会看到更好的性能> 而不是通过入队/出队方法循环。因此,就个人而言,如果 QueueQueue<byte>
is backed by abyte[]
, but you would see better performance if copying to/from the underlying buffer usingArray.Copy
rather than looping through Enqueue/Dequeue methods. So personally, ifQueue<byte>
doesn't give you the performance you want, then you might implement your own queue class that provides QueueMultiple and DequeueMultiple methods.根据传入字节的接收方式以及解析器检查它们的方式,您可能会考虑使用
Queue
。Depending upon how the incoming bytes are received and how the parser examines them, you might consider a
Queue<byte[]>
.我知道我帮不上忙,但你可以自己写一个。
理论部分:
队列应该位于
byte[]
和 2 个索引中,1 个用于头部,1 个用于尾部每次需要添加
k
字节时,您都会移动尾部k 剩下的单位并将创建的数据放入新空间中。
每次需要弹出
k
字节时,您需要将头向左移动k
个单位,并从丢失的空间中获取数据。如果头部和尾部发生碰撞,则需要将容器的大小加倍,并将每一半复制到新的容器中。
请记住:如果您添加
1234
然后弹出 2 个字母,您将得到34
(我不知道是否应该将此帖子标记为社区 wiki)
I know I'm not be helpful, but you can write one of your own.
The theoretic part:
The queue should be in
byte[]
and 2 indexes, 1 for head and 1 for tailEach time you need to add
k
bytes you move tailk
units left and put the in the new space created data there.Each time you need to pop
k
bytes you move headk
units left and take data from the space lost.In case head and tail collide, you need to double the size of the container and copy each half to the new one.
Keep in mind: if you add
1234
and then pop 2 letters you will get34
(I don't know if I should mark this post as community wiki)
这是一个高效的实现我之前写的一个缓冲区:
Here's an efficient implementation of a buffer I wrote a while ago: