在.NET中,使用“ foreach”迭代IEnumerable 的实例将创建副本吗?因此,我应该更喜欢使用“ for”而不是“ foreach”吗?
|
在.NET中,使用\“ foreach \”迭代IEnumerable的实例将创建副本吗?因此,我应该更喜欢使用\“ for \”而不是\“ foreach \”吗?
我写了一些代码来证明这一点:
struct ValueTypeWithOneField
{
private Int64 field1;
}
struct ValueTypeWithFiveField
{
private Int64 field1;
private Int64 field2;
private Int64 field3;
private Int64 field4;
private Int64 field5;
}
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(\"one field\");
Test<ValueTypeWithOneField>();
Console.WriteLine(\"-----------\");
Console.WriteLine(\"Five field\");
Test<ValueTypeWithFiveField>();
Console.ReadLine();
}
static void Test<T>()
{
var test = new List<T>();
for (int i = 0; i < 5000000; i++)
{
test.Add(default(T));
}
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 5; i++)
{
sw.Start();
foreach (var item in test)
{
}
sw.Stop();
Console.WriteLine(\"foreach \" + sw.ElapsedMilliseconds);
sw.Restart();
for (int j = 0; j < test.Count; j++)
{
T temp = test[j];
}
sw.Stop();
Console.WriteLine(\"for \" + sw.ElapsedMilliseconds);
sw.Reset();
}
}}
这是我运行代码后得到的结果:
one field
foreach 68
for 72
foreach 68
for 72
foreach 67
for 72
foreach 64
for 73
foreach 68
for 72
-----------
Five field
foreach 272
for 193
foreach 273
for 191
foreach 272
for 190
foreach 271
for 190
foreach 275
for 188
正如我们在结果中看到的,\“ foreach \”总是比\“ for \”花费更多的时间。
因此,在遍历值类型的通用集合时,我应该更喜欢使用\“ for \”而不是\“ foreach \”吗?
注意:感谢您的提醒,我编辑了代码和结果。但仍然,foreach的运行速度比foreach慢。
没有找到相关结果
已邀请:
8 个回复
疼嘶桐
版本中,您实际上是在旋转枚举数并从列表中检索每个值(即使您没有使用它)。在
版本中,除了查看
属性外,您对列表完全不做任何事情。本质上,您正在测试遍历集合的枚举器与将整数变量递增相等次数相比的性能。 要创建奇偶校验,您需要声明一个临时变量,并在“ 3”循环的每次迭代中分配它。 话虽如此,您的问题的答案是肯定的。每次赋值或
语句都会创建该值的副本。 性能 这种伪代码分解应解释为什么在这种特殊情况下,
比使用
要慢一些:
:
:
如您所见,在
实现中代码很少,而
在
之上有一个抽象层(枚举器)。我使用
循环编写了
,以类似的方式显示了两个版本。 说了这么多... 您正在谈论执行时间的微小差异。使用使代码更清晰,更小的循环,在这种情况下,看起来像
。
厘恼轨
蜂佬渺
细瑞
周期中,我看不到您实际从
访问项目。如果将
添加到
周期中,您会发现其性能(实际上)是相同的。 每次对value-type属性的访问都会创建一个副本,可以在
周期中使用
或在
上使用
。
烷刨画颠离
惭法搽
悸翠疮武昏
这将创建一个变量“ 30”,并在每次迭代时从集合中获取下一个对象,并将其分配给“ 30”。这种获取和分配不应创建副本,但是访问基础集合并将正确的值分配给变量确实需要花费时间。 然后,您有以下代码:
这根本不访问基础集合。它不会在每次迭代中读取和分配变量。它只是将整数增加33倍,因此当然更快。如果编译器很聪明,它将看到循环中没有任何操作发生,而只是优化整个过程。 公平的比较将把第二部分代码替换为:
这更类似于您的
循环所做的事情。 至于使用哪种,这实际上是个人喜好和编码风格的问题。从可读性的角度来看,我通常认为
比
更清晰。
僻朵庙惩竣
至
在XNA游戏中,如果集合很大或经常调用(例如Update方法)。 快一点 减少垃圾 垃圾是至关重要的,因为Compact Framework GC每1MB分配都会触发一次,因此,它可能导致令人讨厌的冻结。
要回复问题请先登录或注册