Asp.net Lambda表达式比foreach语句慢?
我做了一个小实验来测试lamdba表达式是否能比foreach语句更快地检索结果。但是,兰姆达失败了Asp.net Lambda表达式比foreach语句慢?,asp.net,linq,Asp.net,Linq,我做了一个小实验来测试lamdba表达式是否能比foreach语句更快地检索结果。但是,兰姆达失败了 System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); st.Start(); List<int> lst = new List<int>(); foreach (GridViewRow item in GridView1.Rows)
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
System.Diagnostics.Stopwatch st=新的System.Diagnostics.Stopwatch();
st.Start();
List lst=新列表();
foreach(GridView1.Rows中的GridViewRow项)
{
如果(((复选框)项.FindControl(“检查”)).Checked)
{
lst.Add(Convert.ToInt32(((Label)item.FindControl(“Id”)).Text));
}
}
st.Stop();
Response.Write(st.appeased.ToString());
回答。写(“
”);
圣重置();
st.Start();
List lstRank=GridView1.Rows.OfType()。其中(s=>((复选框)s.FindControl(“检查”)。选中)
.Select(s=>Convert.ToInt32(((Label)s.FindControl(“Id”)).Text)).ToList();
st.Stop();
Response.Write(st.appeased.ToString());
int i=0;
输出
00:00:00.0000249
00:00:00.0002464
为什么lambda比foreach慢。这可能是lambda表达式的一个缺点从技术上讲,您的两种方法并不相同。有一些不同之处,例如使用“
of type
”在继续之前过滤集合。您最好使用“Cast()
”,因为您知道每个元素都属于GridViewRow类型
另外,您真的需要Linq语句末尾的
ToList()
,因为您的Linq查询现在可以迭代并执行,而不必转换回列表?lambda表达式的开销很小,因为它们是在运行时“编译”的。我想这就是你在“基准”中看到的。对于每个。。。是一个完全编译的语句
可以预编译lambda表达式。看。也许您想重新编写代码并再次测试。我不会谈论代码的正确性,但我想有机会解释一下一般规则 在软件开发中,性能损失与消耗水平成反比。 在这种情况下,foreach比LINQ(更抽象)更快是很正常的。 如果您将其与经典for(for(inti:i++l等)进行比较,它将比foreach更快。 访问对象认为接口比访问具体对象慢:接口已经是一个非常小的抽象级别。 您编写的代码将与机器语言“接近”的速度一样快,但当然可读性和可维护性较差。 问题是如何为我们正在开发的东西找到合适的抽象级别,同时关注性能和代码可读性
您不需要使用MVC模式来创建一个在转发器上显示表格的单页网站:-)您可以在这里查看一下:这里您的基准运行时间不够长,无法真正发挥作用。我不相信测量时间不到几秒钟的基准测试。如果
GridView1.Rows
包含一些不是从GridViewRow
派生的内容,那么foreach
版本将抛出类型异常。不,这里不会发生这种情况。这些是普通的lambda,不是表达式树。@Daniel:一个愚蠢的问题和一点OT:普通的lambda完全编译好了吗?找不到说明此内容的链接。你能帮忙吗?对于一个普通的lambda,想象一下编译器只是把你的代码移到一个单独的方法中,然后为它发明一个名称。事实上,您不需要想象:如果使用ILDASM或Reflector查看生成的代码,您可以找到编译器生成的名称。如果lambda从封闭方法捕获(“关闭”)一个局部变量,该变量将成为编译器生成的类的一个字段,该类的一个对象将由外部方法分配,以便可以共享该变量。因此,在运行时不需要进行特殊的解释/编译。@Daniel:非常感谢您的详细和熟练的解释。我很抱歉——就像我问你的那样——这件事没有什么好名声。