2009-12-08 55 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次按鈕嗎?如果是這樣,它可能可能是一個問題。