C# 列表中的索引太慢。更快的解决方案?
我有一个通用列表,它必须是一个保留的顺序,这样我就可以检索列表中某个对象的索引。问题是IndexOf太慢了。如果我将IndexOf注释掉,代码将尽可能快地运行。有没有更好的方法,比如为c#保留有序哈希列表 谢谢, 内特C# 列表中的索引太慢。更快的解决方案?,c#,list,performance,indexof,C#,List,Performance,Indexof,我有一个通用列表,它必须是一个保留的顺序,这样我就可以检索列表中某个对象的索引。问题是IndexOf太慢了。如果我将IndexOf注释掉,代码将尽可能快地运行。有没有更好的方法,比如为c#保留有序哈希列表 谢谢, 内特 编辑- 添加/插入项目的顺序就是它需要的顺序。不需要对它们进行排序。此外,该列表还可能经常更新、添加、删除和插入。基本上,我需要将对象转换为索引,因为它们在网格控件中表示,所以我可以基于索引对网格控件执行操作 好吧,你们并没有理由要订购散列列表……这就是重点。但是,哈希列表应该
- 编辑- 添加/插入项目的顺序就是它需要的顺序。不需要对它们进行排序。此外,该列表还可能经常更新、添加、删除和插入。基本上,我需要将对象转换为索引,因为它们在网格控件中表示,所以我可以基于索引对网格控件执行操作
列表(T)
中的元素[…]此方法是一个O(logn)操作,其中n是范围内的元素数。”如果您使用的是List类,则可以在初始填充后使用Sort方法对其进行排序,然后使用BinarySearch方法查找适当的元素。如果需要对项目进行排序,我建议使用or类。区别如下
使用的内存少于SortedList
SortedDictionary
具有更快的插入和删除操作 未排序的数据:O(log n)而不是SortedDictionary
SortedList的O(n)
- 如果列表是从排序数据一次填充的,
比分类词典快SortedList
如果您只想保留顺序,那么只需使用一个,并将项存储为键,将索引存储为值。缺点是重新排序项目、插入或删除的成本非常高。如果没有排序,但需要保留顺序,则可以有一个单独的
字典,其中包含每个元素的索引
如果您想要一个排序的列表,那么请检查以前的帖子-您可以在.Net 3.5中使用SortedList
,或者在较旧的.Net版本中对其进行排序并使用BinarySearch
[编辑]你可以在网上找到类似的例子,例如:。这一个在内部使用ArrayList和HashTable,但是您可以轻松地将其设置为泛型
[Edit2]哎呀。。我给你的例子并没有像我开始描述的那样实现IndexOf。。。但是你得到了一点-一个列表应该是有序的,另一个用于快速查找。我不确定C#中的细节,但是你可以对它进行排序(快速排序?),然后对它使用二进制搜索(二进制搜索性能是O(log2(N)),而不是顺序的,比如indexOf,它是O(N))。(重要提示:对于二进制搜索,必须对结构进行排序)
在向数据结构中插入项目时,也可以尝试修改二进制搜索来查找插入点,或者如果要添加一个大组,则可以添加项目,然后对其进行排序
唯一的问题是插入速度会变慢。如果列表中对象的顺序要保留,那么我能想到的唯一方法就是在列表中添加对象时告诉对象其索引位置。通过这种方式,您可以查询对象以在列表中获取其索引。缺点是,在我看来,这是一个很大的缺点,插入的对象现在依赖于列表 请参见下面的内容
似乎编写自己的方法来检索索引要比使用IndexOf方法快得多,因为它根据类型调用虚拟方法
这样做可能会提高你的表现。我编写了一个小单元测试来验证这是否提高了搜索的性能,在一个包含10000个项目的列表中,它确实提高了大约15倍
static int GetIndex(IList<Item> list, Item value)
{
for (int index = 0; index < list.Count; index++)
{
if (list[index] == value)
{
return index;
}
}
return -1;
}
static int GetIndex(IList列表,项值)
{
for(int index=0;index
code?您在列表中存储了什么?顺序重要吗?您是在尝试检索对象本身还是仅检索对象的索引?有关您所做工作的更多详细信息?能否请您更具体一些?你在做什么操作使得indexOf如此缓慢?您是否希望优化查找?插入/删除的速度要求是什么?是否需要项目集合是连续的?你能用散列集来代替吗?有序意味着排序,或者意味着必须保留顺序?我相信他只是指“保留顺序”,而不是排序。我考虑过使用字典方法。我不喜欢它的一点是必须更新字典中插入/删除之后的每个条目。但我还没有排除这一点。在插入/删除过程中,如果不牺牲一点速度,就无法加快IndexOf的速度……我最终所做的,而且性能得到了相当好的提高,是通过在调用IndexOf时将对象作为键添加到DICIARY中,并将索引作为值添加到列表中对象的索引来实现的。这样,如果再次调用它,它就可以在字典中查找值。如果列表有任何变化,我就清除字典。另一个答案与下面的答案类似,但我会将此答案标记为答案,因为它有更多的投票权。@NastyNateDoggy:这听起来是最好的解决方案-延迟缓存将降低内存使用率。是的,字典是我考虑过的一种方法,但会增加维护和性能损失。感谢回复。我也曾考虑过这一点,但选择了我在“接受”标题下的评论中所描述的内容