C#,. NET4。
我们有一些性能关键代码导致了一些问题。它是一种经过修改的队列,实际上是由List支持的。我想知道在索引0处删除元素是多么昂贵。想到的问题是:
我一直认为RemovedAt对于列表是O(1)。是这样的吗?
答案 0 :(得分:23)
List<T>
由一个简单数组支持,另外还有一个size
字段,表示该数组的哪个部分实际上在使用中。 (为了未来的增长)。
除非您添加太多元素或调用TrimExcess
,否则不会调整数组的大小。
Remove
为O(n)
,因为它需要将列表的其余部分向下移动一个。
相反,您可以使用LinkedList<T>
(除非您使用随机访问),或编写自己的列表来跟踪前面的空白部分。
答案 1 :(得分:9)
是O(n)。它甚至在MSDN上都这么说。
此方法是O(n)操作,其中n是(Count - index)。
答案 2 :(得分:2)
据我所知,它应该是一个O( n )操作。在内部,它使用Array.Copy
(这是一个O( n )操作)将0之后的元素复制回列表的后备数组中。来自Reflector:
public void RemoveAt(int index) {
if (index >= this._size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
this._size--;
if (index < this._size) {
Array.Copy(this._items, index + 1, this._items, index, this._size - index);
}
this._items[this._size] = default(T);
this._version++;
}
因此,对于任何有效的数组索引i,它将i + 1中的所有后续元素复制到i。