views:

139

answers:

4

I have the following click event.

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
        }
    }

Do I suffer a performance hit since I'm declaring an instance of the RadEditor and DropDownList with every iteration, or is the compiler smart enough to know to reuse the instances?

A: 

You shouldn't incur any performance hit as those control should already exist on the page. Otherwise how could you find them?

+3  A: 

Its not creating new instances (unless there are custom explicit cast operators on the controls that are creating them). Find will find an exising object and cast it for you.

Preet Sangha
This is not what he is asking about.
Jason
Maybe it's not what he meant, but it is what he asked.
Joel Mueller
No, it's not. He asked about the declarations that are inside the loop and whether or not there is a hit on every iteration. This is very clear.
Jason
@Jason the OP did say `declaring an instance of the RadEditor and DropDownList with every iteration` which is not what's happening. An instance is not being declared, a reference to it is being acquired.
Rex M
Do you not see `RadEditor re` and `DropDownList ddl`? These are declarations. They are happening on every iteration. I believe this is what he is referring to.
Jason
@Jason- actually it looks like the original poster doesn't fully understand references.
RichardOD
Forgive me; I didn't mean to be so unclear. I simply wanted to know if memory was being allocated for the RadEditor and DropDownList variables with **every** iteration, since I declared the variables solely within the scope of the loop. Guess I need be a little more explanative next time. :)
Jagd
Lets move on please - guys. Thanks for the comment Jagd
Preet Sangha
+2  A: 

First, even worrying about this is a micro-optimization; you shouldn't worry about it until you are studying the performance of your application and profiling suggests that this method and this loop are bottlenecks. Second, yes the compiler will reuse the same instance of the local variables re and ddl.

Here's a very simple example:

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

Here's the 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

}

Notice that in the locals section, the variable i is declared as occupying the second location on the stack and this is where the result of get_Length is repeatedly being stored on each iteration through the loop. (I have highlighted the relevant lines with --->s in the margin.)

Jason
Thank you, Jason. This is exactly what I was looking for! A developer that I work with said that it is inefficient to have variables declared within a loop. But I had a hard time imagining -what with how smart compilers are - that the compiler would re-allocate new memory with each iteration. It seemed to me that the compiler would do exactly as you showed it to do, but I was unable to prove this for myself because I don't know how to read or get it. Thanks again!
Jagd
A: 

Performance hit? Can you click buttons 1000 times per second? If so, it might be an issue.

Mike Dunlavey