C# 在C语言中,更快地遍历集合的所有元素#
我使用的语言是C 让我们有一个C# 在C语言中,更快地遍历集合的所有元素#,c#,foreach,C#,Foreach,我使用的语言是C 让我们有一个T类型的对象列表 List<T> collection = new List<T>{.....}; 及 第二种方式是否比第一种好?为什么 提前感谢您的回答。它们完全一样var是方便使用的语法糖。它对遍历列表的速度没有影响 我使用var遵循的经验法则是,仅当对象的类型出现在赋值的右侧时才使用它,因此在这种情况下,我更愿意在foreach中明确指定类型,以使其他工程师更清楚,但这取决于个人选择。如果将鼠标悬停在Visual Studio中的va
T
类型的对象列表
List<T> collection = new List<T>{.....};
及
第二种方式是否比第一种好?为什么
提前感谢您的回答。它们完全一样
var
是方便使用的语法糖。它对遍历列表的速度没有影响
我使用var
遵循的经验法则是,仅当对象的类型出现在赋值的右侧时才使用它,因此在这种情况下,我更愿意在foreach
中明确指定类型,以使其他工程师更清楚,但这取决于个人选择。如果将鼠标悬停在Visual Studio中的var
上,它将显示类型(假设它可以推断应该是什么)。引用MSDN:
隐式类型的局部变量是强类型的,就像
您自己声明了类型,但编译器确定了类型
所以
它们完全一样
现在,为了“更好”,这将在很大程度上取决于您的参数来判断它。如果是速度,那么for
循环的可能比foreach
好,并且T[]
比List好。要点:
列表上的循环比for
列表上的循环便宜2倍多foreach
- 在阵列上循环大约比在列表上循环便宜2倍
- 因此,使用for在数组上循环比使用
在列表上循环便宜5倍(我相信,这是我们大家都做的)foreach
参考资料:在同一个集合中迭代没有更快的方法 无论您使用什么,您自己的循环或扩展方法都是一样的。当您使用
var
时,它仍然编译成相同的东西
唯一的区别可能是,如果使用Dictionary,它在搜索值方面将比
列表
或集合
更快。字典是为搜索优化而设计的如果你比较IL代码,你会发现它们实际上是100%相同的。
var
是唯一的语法糖:
C#代码:
列表集合=新列表();
增加第(1)款;
增加(2);
增加(3);
foreach(集合中的var myInt)
{
控制台写入线(myInt);
}
foreach(集合中的变量T)
{
控制台写入线(T);
}
bool标志;
System.Collections.Generic.List List=新的System.Collections.Generic.List();
增加第(1)款;
增加(2);
增加(3);
System.Collections.Generic.List.Enumerator Enumerator=List.GetEnumerator();
尝试
{
while(旗帜)
{
int i1=枚举数。获取当前值();
系统控制台写入线(i1);
flag=enumerator.MoveNext();
}
}
最后
{
枚举数。Dispose();
}
枚举器=list.GetEnumerator();
尝试
{
while(旗帜)
{
int i2=枚举数。获取当前值();
系统控制台写入线(i2);
flag=enumerator.MoveNext();
}
}
最后
{
枚举数。Dispose();
}
1st-way(使用var)可能更易于阅读。
考虑这一点:
List<User> list = new List<User>();
var users = list.GroupBy(x => x.Name).OrderBy(x => x.Key);
foreach (var user in users)
{
//blah
}
List List=新列表();
var users=list.GroupBy(x=>x.Name).OrderBy(x=>x.Key);
foreach(用户中的var用户)
{
//废话
}
vs
foreach(System.Linq.i将用户分组到用户中)
{
}
我认为这是在第一时间使用var的主要原因。
完全一样
在运行时没有var
这样的东西。两者将发出相同的编译代码。唯一需要注意的是,当您创建foreach
时,是否执行了导致编译器发出类型强制转换操作的操作。例如,List o
foreach(o中的字符串i)
将添加IL调用,以尝试将迭代器的当前项转换为字符串。这是对支持旧的.NET集合的一种回溯。一种更快的方法可能是使用for
而不是foreach
,我已经了解到它在某些条件下的性能确实更好。测量它并找出答案。您已经以两种方式编写了代码;现在运行它,看看哪一个更快。克里斯是正确的,使用var对速度毫无影响-编译时,两个循环都将转换为相同的字节码。有时var
不仅仅是一种“语法糖”,而且是必须的。例如,当您迭代一个匿名对象列表时。@haim770确实,这是匿名类型的必备工具-谢谢@haim770嗯,你不知道,但如果你不知道,那就是一个巨大的皮塔。@ScottChamberlain,“皮塔”?如果你想编写一个简单的foreach
,就像你以前为“常规”类型编写的那样,你必须这样做。这是一个“更好的可读性”的非常糟糕的例子。考虑到它使用的是完全命名空间的类型+它是一个组,用户名是user
。我认为这是使用var
关键字的理想人选。@jamesups。。我是说第一条路。我必须同意@James的观点。这两个街区不相等。而可读性,就像美一样,也在旁观者的眼中;第一个块的前三行有助于理解比第二个块多得多的内容。@OnoSendai foreach(用户中的var user)。。。和foreach(System.Linq.IGrouping user in users)做同样的事情,你同意吗?对于linq结果,我通常不想知道确切的类型,所以我更喜欢使用var而不是键入30个字符长的类型——我非常喜欢
foreach(T item in collection)
{
// code goes here
}
var i = 10; // implicitly typed
int i = 10; //explicitly typed
List<int> collection = new List<int>();
collection.Add(1);
collection.Add(2);
collection.Add(3);
foreach (var myInt in collection)
{
Console.WriteLine(myInt);
}
foreach (var T in collection)
{
Console.WriteLine(T);
}
bool flag;
System.Collections.Generic.List<int> list = new System.Collections.Generic.List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
System.Collections.Generic.List<int>.Enumerator enumerator = list.GetEnumerator();
try
{
while (flag)
{
int i1 = enumerator.get_Current();
System.Console.WriteLine(i1);
flag = enumerator.MoveNext();
}
}
finally
{
enumerator.Dispose();
}
enumerator = list.GetEnumerator();
try
{
while (flag)
{
int i2 = enumerator.get_Current();
System.Console.WriteLine(i2);
flag = enumerator.MoveNext();
}
}
finally
{
enumerator.Dispose();
}
List<User> list = new List<User>();
var users = list.GroupBy(x => x.Name).OrderBy(x => x.Key);
foreach (var user in users)
{
//blah
}
foreach (System.Linq.IGrouping<string, User> user in users)
{
}