List <t> .IndexOf()是如何用C#实现的?</t>

时间:2010-03-29 17:47:33

标签: c# .net performance list

我在考虑调用List<T>.Indexof(item)的表现。我不确定它对于顺序算法的O(n)性能还是二叉树的O(log(n))性能?

8 个答案:

答案 0 :(得分:32)

使用Reflector for .NET,我们可以看到:

public int IndexOf(T item)
{
    return Array.IndexOf<T>(this._items, item, 0, this._size);
}

public static int IndexOf<T>(T[] array, T value, int startIndex, int count)
{
    return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count);
}

internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
{
    int num = startIndex + count;
    for (int i = startIndex; i < num; i++)
    {
        if (this.Equals(array[i], value))
            return i;
    }
    return -1;
}

答案 1 :(得分:32)

根据MSDNO(n)

  

此方法执行线性搜索;因此,此方法是O(n)操作,其中n是Count。

答案 2 :(得分:14)

List<T>由平面数组支持,因此list.IndexOf(item)为O(n)。

答案 3 :(得分:7)

List<T>.IndexOf是O(n),实际上对于一组无序的n个元素是最优的。

List<T>.BinarySearch是O(log n),但只有在对List进行排序时才能正常工作。

答案 4 :(得分:4)

如果您需要更快的表演者,请考虑HashSet<T>。这是一种速度与内存的权衡,但如果你重视后者,那么它是值得的。

(它与List<T>不完全相同,它的行为类似于单列字典,但对于您将拥有唯一列表的实例,它是一种方法。)

答案 5 :(得分:4)

我的回答很晚,但我认为值得一提的是,现在您可以直接访问MS来源: http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs

由于.NET BCL代码现已在线提供,因此不再需要反思。

  

实现一个可变大小的List,该List使用要存储的对象数组   要素。 List具有容量,即分配的长度   内部数组。随着元素被添加到List,容量   通过重新分配,列表会根据需要自动增加   内部数组。

作为数组实现并执行 线性搜索 ,您可以轻松推断出IndexOf方法的算法复杂度为 O( n)的

如其他人所述,这些信息可在msdn上公开获取: https://msdn.microsoft.com/en-us/library/e4w08k17(v=vs.110).aspx

  

此方法执行线性搜索;因此,这种方法是一种   O(n)操作,其中n是Count。

同样,您可以查看源代码并最终确定实际在幕后调用Array类的静态帮助器方法IndexOf

http://referencesource.microsoft.com/#mscorlib/system/array.cs

如果列表/数组已预先排序,则可以使用二进制搜索: https://msdn.microsoft.com/en-us/library/w4e7fxsh(v=vs.110).aspx

  

此方法是O(log n)操作,其中n是数字   范围内的元素。

答案 6 :(得分:3)

在幕后使用常规array,事实上IndexOf方法只调用Array.IndexOf。由于数组不对元素进行排序,因此性能为O(n)。

答案 7 :(得分:2)

这是一个老问题,但我认为这个链接会很有趣:Experiment: List internals and performance when adding new elements