Lambda 表达式比 foreach 语句慢?
我做了一个小实验来测试 lamdba 表达式是否可以比 foreach 语句更快地检索结果。但是,Lambda 失败了
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
List<int> lst = new List<int>();
foreach (GridViewRow item in GridView1.Rows)
{
if (((CheckBox)item.FindControl("Check")).Checked)
{
lst.Add(Convert.ToInt32(((Label)item.FindControl("Id")).Text));
}
}
st.Stop();
Response.Write(st.Elapsed.ToString());
Response.Write("<br/><br/><br/>");
st.Reset();
st.Start();
List<int> lstRank = GridView1.Rows.OfType<GridViewRow>().Where(s => ((CheckBox)s.FindControl("Check")).Checked)
.Select(s => Convert.ToInt32(((Label)s.FindControl("Id")).Text)).ToList();
st.Stop();
Response.Write(st.Elapsed.ToString());
int i = 0;
output
00:00:00.0000249
00:00:00.0002464
,为什么 lambda 比 foreach 慢。这可能是 lambda 表达式的一个缺点
I did a small experiment to test whether lamdba expression can retrieve faster results than foreach statement. but, Lambda failed
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
List<int> lst = new List<int>();
foreach (GridViewRow item in GridView1.Rows)
{
if (((CheckBox)item.FindControl("Check")).Checked)
{
lst.Add(Convert.ToInt32(((Label)item.FindControl("Id")).Text));
}
}
st.Stop();
Response.Write(st.Elapsed.ToString());
Response.Write("<br/><br/><br/>");
st.Reset();
st.Start();
List<int> lstRank = GridView1.Rows.OfType<GridViewRow>().Where(s => ((CheckBox)s.FindControl("Check")).Checked)
.Select(s => Convert.ToInt32(((Label)s.FindControl("Id")).Text)).ToList();
st.Stop();
Response.Write(st.Elapsed.ToString());
int i = 0;
output
00:00:00.0000249
00:00:00.0002464
why lambda is slower than foreach. This may be a drawback of lambda expression
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从技术上讲,您的两种方法并不相同。有一些差异,例如使用“
OfType
”,它在继续之前过滤集合。您最好使用“Cast()
”,因为您知道每个元素都是 GridViewRow 类型。另外,您是否真的需要在 Linq 语句末尾花费
ToList()
的费用,因为您的 linq 查询现在已准备好迭代并执行,而不必转换回列表?Technically your 2 approaches are not identical. There are a few differences such as the use of "
OfType
" which is filtering the collection before continuing. You'd be better using "Cast<GridViewRow>()
" as you know each element is of type GridViewRow.Also, do you really need the expense of the
ToList()
at the end of the Linq statement as your linq query is now ready to iterate over and execute rather than having to convert back to a list?lambda 表达式的开销很小,因为它们是在运行时“编译”的。我认为这就是您在“基准”中看到的。对于每个...都是一个完全编译的语句。
您可以预编译 lambda 表达式。请查看此处。也许您想重新编写代码并再次测试。
There is a small overhead with lambda expressions because they are "compiled" at runtime. I think that's what you see in your "benchmark". for each ... is a fully compiled statement.
You can precompile lambda expressions. Look here. Maybe you want to rework your code and test again.
我不会谈论您的代码的正确性,但我想有机会解释一般规则
在软件开发中,性能损失与抽象水平成反比。
在这种情况下,foreach 比 LINQ(更抽象)更快,这是很正常的。
如果将它与经典的 for (for (int i:i++l,etc..) ) 进行比较,它将比 foreach 更快。
访问一个认为接口的对象比访问具体的对象慢:接口已经是一个非常小的抽象级别。
您编写的代码将尽可能快,因为它“接近”机器语言,但当然它的可读性和可维护性会较差。
问题是如何为我们正在开发的内容找到正确的抽象级别,同时关注性能和代码可读性。
您不需要 MVC 模式来制作在中继器上显示表格的单页网站:-)
I won't talk about the correctness of your code but I'd like to get a chance to explain a general rule
In Software Develpment the performance loss is inversely proportional to the level of abtsraction.
In this case in quite normal that foreach is faster then LINQ (which is more abstract).
If you compare it with the classic for (for (int i:i++l,etc..) ) it will be faster than the foreach.
Access an object thought an interface is slower then access the concrete object : the interface is already a very small level of abstraction.
The code you write will be as much fast as it is "close" to the machine language but of course it will be less readable and maintainable.
The matter is how to find the right level of abstraction for what we are developing keeping an eyes on the performance and the code readability.
You won't need MVC pattern for making a one-page web site that shows a table on a Repeater :-)