【问题标题】:Is there a LinkedList collection that supports dictionary type operations是否有支持字典类型操作的 LinkedList 集合
【发布时间】:2023-04-06 12:08:01
【问题描述】:

我最近正在分析一个应用程序,试图找出某些操作为何极其缓慢。我的应用程序中的一个类是基于 LinkedList 的集合。这是一个基本大纲,仅显示了几种方法并删除了一些绒毛:

  public class LinkInfoCollection : PropertyNotificationObject, IEnumerable<LinkInfo>
  {

    private LinkedList<LinkInfo> _items;

    public LinkInfoCollection()
    {
      _items = new LinkedList<LinkInfo>();
    }

    public void Add(LinkInfo item)
    {
      _items.AddLast(item);
    }

    public LinkInfo this[Guid id]
    { get { return _items.SingleOrDefault(i => i.Id == id); } }

  }

该集合用于将超链接(由 LinkInfo 类表示)存储在单个列表中。然而,每个超链接也有一个指向它的超链接列表,以及一个它指向的超链接列表。基本上,它是一个网站的导航地图。因为这意味着当链接相互返回时您可以进行无限递归,所以我将其实现为链表 - 据我了解,这意味着对于每个超链接,无论它被另一个超链接引用多少次,只有对象的一个​​副本。

上例中的 ID 属性是一个 GUID。

有了那个冗长的描述,我的问题很简单 - 根据分析器,在为一个相当小的网站构建此地图时,上面提到的索引器被调用不少于 27906 次。这是一个非凡的数额。我仍然需要确定是否真的有必要多次调用,但同时,我想知道是否有更有效的方法来执行索引器,因为这是分析器确定的主要瓶颈(也是假设它没有说谎!)。我仍然需要链表行为,因为我当然不希望这些超链接的一个副本在我的记忆中徘徊,但我还需要能够通过唯一键访问它们。

有没有人对提高这个索引器的性能有任何建议。我还有另一个使用 URI 而不是 GUID 的索引器,但由于构建传入/传出链接是由 GUID 完成的,因此问题较少。

谢谢; 理查德·莫斯

【问题讨论】:

  • 为什么你需要一个链表行为?
  • 好吧。通常我没有能够无限递归的集合。但是,如果链接 A 指向链接 B,链接 B 也指向链接 A,这意味着您可以愉快地从 a 跳到 b,再从 a 跳到 b,并且永远持续一天。所以我从对 LinkedList 的描述中认为它会更好地完成这项工作。也许我弄错了,一本字典就足够了……但除非我问有更多知识的人,否则我不会知道:)
  • Collections 不关心其内容中的引用。 LinkedList 是非常不适合这项工作的工具。

标签: c# dictionary linked-list


【解决方案1】:

您应该使用Dictionary&lt;Guid, LinkInfo&gt;

【讨论】:

  • 通常我做字典的基础集合,这是我第一次使用LinkedList作为基础。正如 MSDN 所述,“您可以删除节点并重新插入它们,无论是在同一个列表中还是在另一个列表中,这都会导致堆上没有分配额外的对象。”使用字典肯定会否定这个优势吗?还是不值得担心?
  • @Richard:字典的唯一问题是它偶尔需要调整其内部数组的大小(创建一个新数组并丢弃旧数组)。 别担心。如果您担心,您可以提前设置容量以避免不必要的调整大小。
  • 我认为 MSDN 是说 LinkedList 正在使用它的内部 Link 对象做一些事情。我不认为他们的意思是暗示其他集合类会复制插入其中的对象。
  • @David:正确。集合不能可能复制其内容。 (除非它是结构的集合,在这种情况下它必须复制其内容)
【解决方案2】:

您无需使用 LinkedList 即可在内存中仅拥有每个 LinkInfo 的一份副本。请记住,LinkInfo 是一种托管引用类型,因此您可以将它放在任何集合中,它只是对放置在列表中的对象的引用,而不是对象本身的副本。

也就是说,我将 LinkInfo 类实现为包含两个 Guid 列表:一个用于此链接到的事物,一个用于链接到此的事物。我只有一个Dictionary&lt;Guid, LinkInfo&gt; 来存储所有链接。字典是一个非常快速的查找,我认为这将有助于你的表现。

this[] 被调用了 27,000 次这一事实对我来说似乎没什么大不了的,但让它出现在分析器中的可能是对 LinkedListSingleOrDefault 调用。链表最适合需要快速插入和删除的情况,尤其是在列表中间。对于在这里可能更重要的快速查找,让 Dictionary 使用哈希表来完成它的工作。

【讨论】:

    猜你喜欢
    • 2011-07-21
    • 2020-10-11
    • 2014-08-26
    • 2016-08-20
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 2018-09-30
    相关资源
    最近更新 更多