.NET中的性能和foreach循环

时间:2009-12-08 22:31:09

标签: performance foreach

我有以下点击事件。

protected void btnUpdate_Click(object sender, EventArgs e) {
        foreach (GridViewRow gvr in gvEditBulletins.Rows) {
            RadEditor re = (RadEditor)gvr.FindControl("reBulletin");
            DropDownList ddl = (DropDownList)gvr.FindControl("ddlPosition");

            // Business logic
        }
    }

我是否因为每次迭代都声明RadEditor和DropDownList的实例而遭受性能损失,或者编译器是否足够聪明以便知道重用实例?

4 个答案:

答案 0 :(得分:3)

它没有创建新实例(除非在创建它们的控件上有自定义显式强制转换操作符)。 Find会找到一个exising对象并为你投射。

答案 1 :(得分:2)

首先,甚至担心这是微观优化;在研究应用程序的性能之前,您不必担心它,并且分析表明此方法和此循环是瓶颈。其次,是的,编译器将重用局部变量reddl的相同实例。

这是一个非常简单的例子:

class Program {
    static void Main(string[] args) {
        string[] strings = new [] { "hello", "world" };
        foreach (string s in strings) {
            int i = s.Length;
        }
        return;
    }
}

这是IL:

.method private hidebysig static void Main(string[] args) cil managed {
    .entrypoint
    .maxstack 3
    .locals init (
        [0] string[] strings,
        [1] string s,
--->    [2] int32 i,
        [3] string[] CS$0$0000,
        [4] string[] CS$6$0001,
        [5] int32 CS$7$0002,
        [6] bool CS$4$0003)
    L_0000: nop 
    L_0001: ldc.i4.2 
    L_0002: newarr string
    L_0007: stloc.3 
    L_0008: ldloc.3 
    L_0009: ldc.i4.0 
    L_000a: ldstr "hello"
    L_000f: stelem.ref 
    L_0010: ldloc.3 
    L_0011: ldc.i4.1 
    L_0012: ldstr "world"
    L_0017: stelem.ref 
    L_0018: ldloc.3 
    L_0019: stloc.0 
    L_001a: nop 
    L_001b: ldloc.0 
    L_001c: stloc.s CS$6$0001
    L_001e: ldc.i4.0 
    L_001f: stloc.s CS$7$0002
    L_0021: br.s L_0038
    L_0023: ldloc.s CS$6$0001
    L_0025: ldloc.s CS$7$0002
    L_0027: ldelem.ref 
    L_0028: stloc.1 
    L_0029: nop 
    L_002a: ldloc.1 
--->L_002b: callvirt instance int32 [mscorlib]System.String::get_Length()
--->L_0030: stloc.2
    L_0031: nop 
    L_0032: ldloc.s CS$7$0002
    L_0034: ldc.i4.1 
    L_0035: add 
    L_0036: stloc.s CS$7$0002
    L_0038: ldloc.s CS$7$0002
    L_003a: ldloc.s CS$6$0001
    L_003c: ldlen 
    L_003d: conv.i4 
    L_003e: clt 
    L_0040: stloc.s CS$4$0003
    L_0042: ldloc.s CS$4$0003
    L_0044: brtrue.s L_0023
    L_0046: br.s L_0048
    L_0048: ret 

}

请注意,在locals部分中,变量i被声明为占用堆栈上的第二个位置,这是get_Length的结果在循环的每次迭代中重复存储的位置。 (我已在边距中突出显示---> s的相关行。)

答案 2 :(得分:0)

由于页面上已经存在这些控件,因此不应该产生任何性能损失。否则你怎么能找到它们?

答案 3 :(得分:0)

性能如何?你能每秒点击1000次按钮吗?如果是这样,可能成为一个问题。