在 C# 中使用 List 的 foreach 和传统 for 循环<T>
foreach and traditional for-loop with List<T> in C#
在C#中,我刚刚发现没有像C++或Java的迭代器这样的东西。在C++中,有人建议我不要用索引迭代链表,因为从每个循环的第一个节点访问会对性能产生影响。但我在C#中似乎只有两个选择。循环的传统VSforeach。
它在C#中不同吗?与C++不同,for循环没有性能问题?
我还听说foreach
在每次循环迭代中都会创建每个新变量,就像在Java中一样,所以我不知道哪一个适合低端手机。
这并不能完全回答你的问题,但仍然想指出这个假设是错误的:
在C#中,我刚刚发现没有像C++或Java 的迭代器这样的东西
它在C#中被称为枚举器,请参阅IEnumerator<T>
。
还可以考虑使用传统for
循环的代码示例:
static void Main(string[] args)
{
var data = new List<int> { 7, 10, 0 };
for (var it = data.GetEnumerator(); it.MoveNext(); )
{
Console.WriteLine(it.Current);
}
}
无论如何,我不认为有人像这个例子中那样迭代列表或IEnumerable
:)
C#中有一个迭代器的概念,它是IEnumerable<T>
,它可以提供对集合的顺序访问。
List<T>
和LinkedList<T>
都实现了这个接口,并且在这两种情况下都不存在与索引操作的算法复杂性相关的性能损失。
顺便说一句,LinkedList<T>
在.NET中没有快速追加操作的好处,因为在向列表末尾添加项目时,List<T>
有O(1)的摊销时间,而List<T>
对GC的压力较小,因为它由在需要时呈指数增长的阵列存储支持,所以大多数时候都会使用List<T>
。
至于List<T>
的索引访问性能和"相同变量"问题,我认为下面的代码演示了使用场景。
在"同一变量"检查中,您可以看到,在"for"的情况下,变量在外部范围内,而对于foreach
,它在最新编译器版本中的迭代器块的内部范围内(需要检查是哪个版本更改了这一点)。这是非常重要的情况下,你做了一个关闭,代码证明了它
void Main()
{
var n = 10000000;
var list = Enumerable.Range(0, n).ToList();
var array = list.ToArray();
Test(TestForeach, list, "foreach - List");
Test(TestFor, list, "for - List");
Test(TestForeach, array, "foreach - Array");
Test(TestFor, array, "for - Array");
TestSameVariableFor();
TestSameVariableForeach();
}
void TestSameVariableFor()
{
var sum = 0;
List<Action> actions = new List<Action>();
for (var i = 0; i < 2; i++)
{
actions.Add(() => sum += i);
}
foreach (var a in actions)
{
a();
}
Console.WriteLine("For - Sum is {0}", sum);
}
void TestSameVariableForeach()
{
var sum = 0;
List<Action> actions = new List<Action>();
foreach (var i in Enumerable.Range(0, 2))
{
actions.Add(() => sum += i);
}
foreach (var a in actions)
{
a();
}
Console.WriteLine("Foreach - Sum is {0}", sum);
}
void Test(Action<List<int>> action, List<int> list, string what)
{
var sw = Stopwatch.StartNew();
action(list);
sw.Stop();
Console.WriteLine("Elapsed {0}, {1}", sw.ElapsedMilliseconds, what);
Console.WriteLine();
}
void Test(Action<int[]> action, int[] list, string what)
{
var sw = Stopwatch.StartNew();
action(list);
sw.Stop();
Console.WriteLine("Elapsed {0}, {1}", sw.ElapsedMilliseconds, what);
Console.WriteLine();
}
void TestFor(List<int> list)
{
long sum = 0;
var count = list.Count;
for (var i = 0; i < count; i++)
{
sum += i;
}
Console.WriteLine(sum);
}
void TestForeach(List<int> list)
{
long sum = 0;
foreach (var i in list)
{
sum += i;
}
Console.WriteLine(sum);
}
void TestFor(int[] list)
{
long sum = 0;
var count = list.Length;
for (var i = 0; i < count; i++)
{
sum += i;
}
Console.WriteLine(sum);
}
void TestForeach(int[] list)
{
long sum = 0;
foreach (var i in list)
{
sum += i;
}
Console.WriteLine(sum);
}
输出:
49999995000000
Elapsed 37, foreach - List
49999995000000
Elapsed 6, for - List
49999995000000
Elapsed 7, foreach - Array
49999995000000
Elapsed 6, for - Array
For - Sum is 4
Foreach - Sum is 1
更新:以下是描述foreach
语义变化的帖子:C#';s重用foreach中的变量?
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么我的for循环不能正确获取argv
- 在基于范围的for循环中使用结构化绑定声明
- 通过for循环使用用户输入填充列表
- 使用for循环检查数组中的重复项
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 正在使用for循环创建QScatterSerie
- Python中的for循环与C++有何不同
- 在更改for循环的第三部分后,未使用for循环结果
- 在 for 循环中查找问题时遇到困难
- 嵌套for循环C++的问题(初学者)
- 如何用for循环在c++中生成单词三角形
- 如何在for循环中包含两个索引值的测试条件
- 带有多个独立参数的C++For循环
- C++ Python 循环"for i, num in enumerate(list):"版本
- C 多循环 for () 基础知识
- 没有条件值的 FOR 循环"for (int i = 1; ; i++)"无法正常工作
- 为用户提供循环for循环的选项
- 打破循环for循环