【发布时间】:2019-07-03 15:43:04
【问题描述】:
我目前正在订阅多播 UDP。它在一个最大 1000 字节的数据包中传输多条消息,每条消息大约 80 字节。当数据包进来时,我将它们解析为对象,然后将它们存储在字典中。
我收到的每个数据包都带有一个序列号,以便我知道我是否丢弃了任何数据包。
收到大约 10k 个数据包后,我开始到处丢包。
securityDefinition xyz = new securityDefinition(p1,p2,p3,p4,p5...etc);
if (!secDefs.ContainsKey(securityID))
{
secDefs.Add(securityID, xyz); //THIS WILL CAUSE DROPS EVENTUALLY
secDefs.Add(securityID, null); //THIS WORKS JUST FINE
}
else
{
//A repeat definition is received and assuming all
//sequence numbers in the packet line up sequentially, I know i am done
//However if there is a drop somewhere (gap in sequence number),
//I know I am missing something
}
securityDefinition 是一个包含大约 15 个整数、10 个小数和 5 个字符串(每个
是否有更快的方法来实时存储这些对象以跟上快速的 UDP 馈送?我尝试将 securityDefinition 设为结构,我尝试将数据存储在数据表中,我尝试将 secDef 添加到列表和队列中。所有人都有同样的问题。
似乎唯一的瓶颈是将对象放入字典中。创建对象并检查字典以查看它是否已经存在似乎很好。
编辑: 为了澄清一些事情 - 安全定义来自循环中的服务器。大约有 1,000,000 个定义。一旦它们都被发送出去,它们就会被一遍又一遍地再次发送。当我的程序启动时,我需要初始化所有的定义。一旦我得到重复,我知道我已经完成并且可以关闭这个连接。但是,如果我收到一个序列号为 1 的数据包,而下一个数据包是序列号 3,我知道我已经丢弃了数据包 2,并且无法恢复它。
【问题讨论】:
-
看起来你在字典中得到了重复的键,并没有真正删除任何东西。你可能想要一个字典定义如下: Dictionary
> -
也许检查可以完全删除,因为我相信
Add已经进行了一些检查(以确定是否应该抛出异常)。我意识到你提到它不是瓶颈的一部分,但如果你的条目被认为是独一无二的,那么为什么不直接使用secdefs[securityId] = xyz呢?此外,如果您知道“最大定义数”,那么初始化字典的容量可能会有所帮助,因此不必调整大小。 -
“无法恢复”——我以为你说它们在循环中重复,那么你可以在下一次迭代中获取丢失的数据。
-
在下一次迭代中,序列号不会从 0 开始,它们只是相互建立。我唯一能想到的是,如果我知道第 1 次迭代中有 10 次丢弃,我会继续让它循环,直到找到并添加 10 个新的 secDef。我想这会起作用,但它很老套,显然更喜欢一个解决方案来限制/消除掉落。