2009-12-08 43 views
0

我有以下的单击事件。NET中的性能和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中的实例与每次迭代,或者是编译器足够聪明,知道再利用的实例?

回答

2

首先,即使担心这是微型优化;除非您正在研究应用程序的性能,并且分析表明此方法和此循环是瓶颈,否则您不应该担心。其次,编译器会重复使用本地变量reddl的相同实例。

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

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

这里的白细胞介素:

.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 

}

注意,在当地人部,可变i被声明为占据第二位置在堆栈上,这是get_Length的结果在循环的每次迭代中被重复存储的地方。 (我已突出显示与---> s在边缘相关的行。)

+0

谢谢,杰森。这正是我所期待的!我一起工作的开发人员说,在循环中声明变量是低效的。但我很难想象 - 如何使用智能编译器 - 编译器会在每次迭代时重新分配新内存。在我看来,编译器完全按照你所做的那样去做,但是我无法证明这一点,因为我不知道如何读取或得到它。再次感谢! – Jagd 2009-12-09 16:37:48

0

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

3

它不创建新的实例(,除非在创建它们的控件上有自定义显式转换操作符)。寻找将找到一个正在升起的物体并将其投射给你。

+1

这不是他所问的。 – jason 2009-12-08 22:45:36

+1

也许这不是他的意思,但这是他问的。 – 2009-12-08 23:03:32

+0

不,不是。他询问循环内部的声明以及每次迭代是否存在命中。这很清楚。 – jason 2009-12-08 23:52:52

0

表现打?你能每秒点击1000次按钮吗?如果是这样,它可能可能是一个问题。