字典用得不好?

时间:2017-09-01 16:05:38

标签: c# performance dictionary data-structures

我在这里读到,通过字典迭代通常被认为滥用数据结构并使用其他东西。

但是,我无法想出一个更好的方法来完成我想要做的事情。

当扫描标签时,我使用它的ID作为键,值是它所在的区域列表。大约每一秒我检查一下我的字典中的标签是否在两个或更多区域中被看到如果有,请排队等待一些计算。

for (int i = 0; i < TagReads.Count; i++)
{
    var tag = TagReads.ElementAt(i).Value;
    if (tag.ZoneReads.Count > 1)
    {
        Report.Tags.Enqueue(tag);
        Boolean success = false;
        do
        {
            success = TagReads.TryRemove(tag.Epc, out TagInfo outTag);
        } while (!success);
    }
}

我觉得字典在这里是正确的选择,因为可以有很多标签可供查找,但有关此代码的内容让我觉得很差。

就效率而言。目前在我们的小规模测试环境中速度还不错,但是我没有一个好的方法来了解它如何在大规模使用之前直到它投入使用,因此我担心。

3 个答案:

答案 0 :(得分:3)

如果您要在代码中进行大量查找,并且有时只是遍历整个事物,那么我认为字典的使用是可以的。我想指出你对ElementAt的使用更令人担忧。 ElementAt在未实现IList<T>且字典不实现的对象上使用时表现非常差。对于未实现IEnumerables<T>的{​​{1}},找到第n个元素的方式是迭代,因此for循环将为每个元素迭代一次字典。您最好使用标准IList

答案 1 :(得分:3)

我相信有一种替代方法,不涉及迭代一本大词典。

首先,您需要创建一个HashSet<T>个标记,您可以在其中存储已在两个以上区域中检测到的标记。我们称之为tagsDetectedInMoreThanTwoZones

您可以按如下方式重构代码流:

一种。每当您在一个区域中检测到标签时......

  1. 将标签和区域添加到主词典中。
  2. 针对tagsDetectedInMoreThanTwoZones创建一个独占锁定,以避免在 B 中出现意外行为。
  3. 检查密钥是否包含多个区域。如果是true,请将其添加到tagsDetectedInMoreThanTwoZones
  4. 解除对tagsDetectedInMoreThanTwoZones
  5. 的锁定

    B中。每当您需要处理在多个区域中检测到的标记时......

    1. 针对tagsDetectedInMoreThanTwoZones创建一个独占锁,以避免线程试图处理它们。
    2. 迭代tagsDetectedInTwoOrMoreZones
    3. 使用tagsDetectedInMoreThanTwoZones中的每个标记获取当前词典中的区域。
    4. 清除tagsDetectedInMoreThanTwoZones
    5. 解除对tagsDetectedInMoreThanTwoZones的独占锁定。
    6. 现在,您将迭代那些您已经知道在多个区域中检测到的标记!

      从长远来看,你甚至可以创建每个区域的分区,这样你永远不会得到一个tagsDetectedInMoreThanTwoZones集合,有太多的项目需要迭代,每个集合都可以被一个专用的线程使用!

答案 2 :(得分:0)

我觉得这对字典很有用,当你想检查一个ID是否已经在集合中时,可以提供良好的访问速度。