列表上的 IndexOf 太慢。 更快的解决方案?

发布于 2024-07-26 04:58:09 字数 283 浏览 5 评论 0原文

我有通用列表,它必须是保留的顺序,以便我可以检索列表中对象的索引。 问题是 IndexOf 太慢了。 如果我注释掉 IndexOf,代码就会运行得尽可能快。 有没有更好的方法,例如 C# 的保留有序哈希列表?

谢谢, 内特

  • 编辑- 添加/插入项目的顺序是它需要的顺序。 无需对它们进行排序。 此外,此列表有可能经常更新、添加、删除、插入。 基本上,我需要将对象转换为索引,因为它们在网格控件中表示,以便我可以根据索引对网格控件执行操作。

I have generic list which must be a preserved order so I can retrieve the index of an object in the list. The problem is IndexOf is way too slow. If I comment the IndexOf out, the code runs fast as can be. Is there a better way, such as a preserved ordered hash list for c#?

Thanks,
Nate

  • Edit -
    The order in which the items are added/inserted is the order it needs to be. No sorting on them is necessary. Also this list has the potential to be updated often, add, remove, insert. Basically I need to translate the object to an index due to them being represented in a grid control so I can perform operations on the grid control based on index.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

允世 2024-08-02 04:58:10

如果未排序,但需要保留顺序,那么您可以有一个单独的Dictionary,其中包含每个元素的索引。

如果您想要一个排序列表,请查看以前的帖子 - 您可以在 .Net 3.5 中使用 SortedList,或者对其进行排序并在旧版 .Net 版本中使用 BinarySearch。

[编辑]您可以在网上找到类似的示例,例如: OrderedList。 这个内部使用了 ArrayList 和 HashTable,但是您可以轻松地使其通用。

[Edit2] 哎呀..我给你的​​例子没有按照我一开始描述的方式实现 IndexOf ...但是你明白了 - 一个列表应该被排序,另一个列表用于快速查找。

If it's not sorted, but the order needs to be preserved, then you could have a separate Dictionary<YourClass, int> which would contain the index for each element.

If you want a sorted list, then check previous posts - you can use SortedList<Tkey, TValue> in .Net 3.5, or sort it and use BinarySearch in older .Net versions.

[Edit] You can find similar examples on the web, e.g.: OrderedList. This one internally uses an ArrayList and a HashTable, but you can easily make it generic.

[Edit2] Ooops.. the example I gave you doesn't implement IndexOf the way I described at the beginning... But you get the point - one list should be ordered, the other one used for quick lookup.

灼疼热情 2024-08-02 04:58:10

Sort it using List<T>.Sort, then use the List<T>.BinarySearch method: "Searches the entire sorted List(T) for an element [...] This method is an O(log n) operation, where n is the number of elements in the range."

↙厌世 2024-08-02 04:58:10

请参阅此处的本文底部

编写自己的方法来检索索引似乎比使用 IndexOf 方法要快得多,因为它根据类型调用虚拟方法。

因此,这样的事情可能会提高你的表现。 我编写了一个小型单元测试来验证这是否提高了搜索性能,结果确实如此,在包含 10,000 个项目的列表中提高了大约 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;
}

See the bottom of this article here.

It appears that writing your own method to retrieve the index is much quicker than using the IndexOf method, due to the fact that it calls into a virtual method depending on the type.

Something like this may therefore improve your performance. I wrote a small unit test to verify that this improves the performance of the search, and it did, by about 15x in a list with 10,000 items.

static int GetIndex(IList<Item> list, Item value)
{
    for (int index = 0; index < list.Count; index++)
    {
        if (list[index] == value)
        {
             return index;
        } 
    }
    return -1;
}
谁与争疯 2024-08-02 04:58:10

也许您正在寻找 SortedList

Perhaps you are looking for SortedList<TKey, TValue>?

执手闯天涯 2024-08-02 04:58:10

如果列表中对象的顺序必须要保留,那么我能想到的获得最快访问权限的唯一方法就是告诉对象它的索引位置是什么将其添加到列表中。 这样您就可以查询对象以获取其在列表中的索引。 缺点,在我看来,这是一个很大的缺点,即插入的对象现在依赖于列表。

If the order of the objects in the list has to be preserved then the only way I can think of where you're going to get the fastest possible access is to tell the object what its index position is when its added etc to the list. That way you can query the object to get its index in the list. The downside, and its a big downside in my view, is that the inserted objects now have a dependency on the list.

街角迷惘 2024-08-02 04:58:10

我建议使用 SortedList SortedDictionary 类(如果您需要对项目进行排序)。 差异如下。

  • SortedList 使用的内存少于 SortedDictionary

  • SortedDictionary 具有更快的插入和删除操作
    未排序数据:SortedList 的 O(log n) 相对于 O(n)。

  • 如果列表是从排序数据一次性填充的,SortedList
    SortedDictionary 更快。​​

如果您只想保留顺序,则可以使用 Dictionary< ;TKey, TValue> 并将项目存储为键,将索引存储为值。 缺点是对项目重新排序、插入或删除的成本非常高。

I suggest to use the SortedList<TKey, TValue> or SortedDictionary<TKey, TValue> class if you need the items sorted. The differences are the following.

  • SortedList<TKey, TValue> uses less memory than SortedDictionary<TKey, TValue>.

  • SortedDictionary<TKey, TValue> has faster insertion and removal operations for
    unsorted data: O(log n) as opposed to O(n) for SortedList<TKey, TValue>.

  • If the list is populated all at once from sorted data,SortedList<TKey, TValue> is
    faster than SortedDictionary<TKey, TValue>.

If you just want to preserve the ordering, you can just use a Dictionary<TKey, TValue> and store the item as key and the index as value. The drawback is that reordering the items, insertions, or deletion are quite expensive to do.

街角迷惘 2024-08-02 04:58:10

好吧,你没有理由必须订购一个哈希列表……这就是重点。 然而,哈希列表应该很容易做到这一点。

Well there is no reason you should ever have to order a hash list...that's kind of the point. However, a hash list should do the trick quite readily.

我的黑色迷你裙 2024-08-02 04:58:10

如果您使用的是 List 类,那么您可以在最初填充后使用 Sort 方法对其进行排序,然后使用 BinarySearch 方法查找适当的元素。

If you are using the List class then you could use the Sort method to sort it after is initially populated then use the BinarySearch Method to find the appropriate element.

流年已逝 2024-08-02 04:58:10

我不确定 C# 中的细节,但您也许可以对其进行排序(QuickSort?),然后对其使用二分搜索(BinarySearch 性能为 O(log2(N)),而不是顺序搜索,例如 indexOf,其中是 O(n))。 (重要提示:对于二分搜索,您的结构必须经过排序)

当您将项目插入数据结构时,您也可以尝试修改后的二分搜索来查找插入点,或者如果您要添加一个大组,您可以添加然后对它们进行排序。

唯一的问题是插入速度会比较慢。

I'm not sure about specifics in C#, but you might be able to sort it (QuickSort?) and then use a binary search on it (BinarySearch performance is O(log2(N)), versus Sequential, such as indexOf, which is O(n)). (IMPORTANT: For a Binary Search, your structure must be sorted)

When you insert items to your data structure, you could try a modified binary search to find the insertion point as well, or if you are adding a large group, you would add them and then sort them.

The only issue is that insertion will be slower.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文