在List <t>上执行for / while循环与foreach循环的性能

时间:2017-02-23 19:45:14

标签: c# list for-loop foreach while-loop

关于数组和for的{​​{1}}和foreach循环的性能有很多帖子。不幸的是,他们主要处理与IEnumerable循环相关的开销,而我无法找到关于他们在链接列表上的表现的任何明确内容 - 或者更确切地说是foreach

为了简单起见,我将把我的问题作为两个假设提出来,并询问它们是否正确。

假设1

当我运行以下代码时:

List<T>

循环迭代将按如下方式执行:

  

0:你有一个指向节点0的指针。在节点0的项目上调用List<Foo> list = new List<Foo>(); //(list is filled here) foreach (Foo f in list) { f.baz(); } 。在节点0之后将指针移动到节点。

     

1:您有一个指向节点1的指针。在节点1的项目上调用baz()。在节点1之后将指针移动到节点。

     

2:你有一个指向节点2的指针。在节点2的项目上调用baz()。在节点2之后将指针移动到节点。

     

...

     

n:你有一个指向节点n的指针。在节点n的项目上调用baz()。在节点n之后将指针移动到节点。

换句话说,上面的代码具有O(n)复杂度。

假设2

当我运行以下代码时:

baz()

或以下代码:

List<Foo> list = new List<Foo>();

//(list is filled here)

for (int i = 0; i < list.Count; i++)
{
    list[i].baz();
}

循环迭代将按如下方式执行:

  

0:你有一个指向List<Foo> list = new List<Foo>(); //(list is filled here) int i = 0; while (i < list.Count) { list[i].baz(); i++; } 的指针。从list获取指向节点0的指针。在节点0的项目上调用list

     

1:你有一个指向baz()的指针。从list获取指向节点0的指针。在节点0之后将指针移动到节点。在节点1的项目上调用list

     

2:你有一个指向baz()的指针。从list获取指向节点0的指针。在节点0之后将指针移动到节点。在节点1之后将指针移动到节点。在节点2的项目上调用list

     

...

     

n:你有一个指向baz()的指针。从list获取指向节点0的指针。在节点0之后将指针移动到节点。在节点1之后将指针移动到节点。将节点移动到节点2之后的节点。 [...] 将节点移动到节点后的节点(n-2 )。将指针移动到节点(n-1)之后的节点。在节点n的项目上调用list

换句话说,上面的代码具有O(n 2 )复杂度。

我的假设是否正确?

1 个答案:

答案 0 :(得分:1)

不,你的假设是不正确的。 List<T>数据类型由数组支持,而不是链接列表。逻辑是

  

0:你有一个参考列表。获取内部数组并直接跳转到第0个索引。呼叫   baz()在节点0的项目上。

     

1:你有参考列表。获取内部数组并直接跳转到第一个索引的偏移量。呼叫   baz()在节点1的项目上。

     

2:你有一个参考列表。获取内部数组并直接跳转到第二个索引的偏移量。呼叫   baz()在节点2的项目上。

     

...

     

n:你有一个参考列表。获取内部数组并直接跳转到第n个索引的偏移量。呼叫   baz()在节点n的项目上。

如果使用LinkedList<T>您的描述是正确的,但LinkedList<T>没有索引器属性[i],那么您将无法传入索引来检索你的代码示例。