我最近在分析一个应用程序,试图弄清楚为什么某些操作非常慢。我的应用程序中的一个类是基于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完成的,因此问题较小。
感谢; 理查德莫斯
答案 0 :(得分:5)
您应该使用Dictionary<Guid, LinkInfo>
。
答案 1 :(得分:2)
您不需要使用LinkedList就可以在内存中只拥有每个LinkInfo的一个副本。请记住,LinkInfo是一个托管引用类型,因此您可以将它放在任何集合中,它只是对放置在列表中的对象的引用,而不是对象本身的副本。
那就是说,我将LinkInfo类实现为包含两个Guids列表:一个用于链接到的东西,一个用于链接到此的东西。我只有一个Dictionary<Guid, LinkInfo>
来存储所有链接。字典是一个非常快速的查找,我认为这将有助于你的表现。
这个[]被称为27,000次的事实对我来说似乎不是什么大不了的事,但是它在你的探查器中出现的原因可能是SingleOrDefault
对LinkedList
的调用。链接列表最适合您需要快速插入的情况。删除,特别是在列表中间。对于快速查找(这可能更重要),让Dictionary使用哈希表进行工作。