Tom Goff's .Net Musings

Tidbits of information regarding .Net, C#, and SQL Server.

Coding and Accessing Properties

leave a comment »

I was recently re-reading parts of “CLR via C#” by Jeffery Richter. In the book, Mr. Richter wished that Properties were not supported in .Net framework for various reasons. The one reason that caught my eye was that a “property can take a long time to execute”.

I use properties through-out my code, for various reasons (XmlSerializer and PropertyGrid are the first two that jump to mind). I’m probably guilty of creating properties that may be a bit to expensive to be properties. Although, I’ve never run into any performance issues relating to them. Regardless, I’m always looking for ways to squeeze a bit more speed/memory from my applications.

So I created a simple class with a single property that does more work than it should:

    public class Class1 { 
        public Int32 Sum { 
            get { 
                Int32 retVal = 0; 
                for (Int32 i = 1; i <= 100; i++) 
                    retVal += i; 
                return retVal; 
            } 
        } 
    }

I then accessed this property as follows:

    Class1 c1 = new Class1(); 
    for (Int32 i = 0; i < c1.Sum; i++) { 
        Console.WriteLine(i.ToString()); 
    }

This resulted in the following compiled IL code:

    .maxstack 2 
    .locals init ( 
        [0] class TestApp.Class1 c1, 
        [1] int32 i) 
    L_0000: newobj instance void TestApp.Class1::.ctor() 
    L_0005: stloc.0 
    L_0006: ldc.i4.0 
    L_0007: stloc.1 
    L_0008: br.s L_001a 
    L_000a: ldloca.s i 
    L_000c: call instance string [mscorlib]System.Int32::ToString() 
    L_0011: call void [mscorlib]System.Console::WriteLine(string) 
    L_0016: ldloc.1 
    L_0017: ldc.i4.1 
    L_0018: add 
    L_0019: stloc.1 
    L_001a: ldloc.1 
    L_001b: ldloc.0 
*-> L_001c: callvirt instance int32 TestApp.Class1::get_Sum() 
    L_0021: blt.s L_000a 
    L_0023: ret 

As you can see by the marked line, the property is access for each iteration of the loop. I then updated the property access to save the value in a local variable as follows:

    Class1 c1 = new Class1(); 
    Int32 sum = c1.Sum; 
    for (Int32 i = 0; i < sum; i++) { 
        Console.WriteLine(i.ToString()); 
    }

This resulted in the following compiled IL code:

    .maxstack 2 
    .locals init ( 
        [0] class TestApp.Class1 c1, 
*->     [1] int32 sum, 
        [2] int32 i) 
    L_0000: newobj instance void TestApp.Class1::.ctor() 
    L_0005: stloc.0 
    L_0006: ldloc.0 
*-> L_0007: callvirt instance int32 TestApp.Class1::get_Sum() 
*-> L_000c: stloc.1 
    L_000d: ldc.i4.0 
    L_000e: stloc.2 
    L_000f: br.s L_0021 
    L_0011: ldloca.s i 
    L_0013: call instance string [mscorlib]System.Int32::ToString() 
    L_0018: call void [mscorlib]System.Console::WriteLine(string) 
    L_001d: ldloc.2 
    L_001e: ldc.i4.1 
    L_001f: add 
    L_0020: stloc.2 
    L_0021: ldloc.2 
*-> L_0022: ldloc.1 
    L_0023: blt.s L_0011 
    L_0025: ret 
}

As expected, the new code only access the property once outside the loop. The new local variable “sum” is then used inside the loop.

Obviously, this is a simple example and would not result in a noticable speed improvement, but it illustrates the point. I don’t think a general rule can be defined (e.g. always save the property value in a local variable), because every case varies. There may be cases where  the code expecting the value to change. Such as:

    while (false == c1.IsCompleted) { 
        ... 
    }

This is just something to keep in mind when coding and using properties. Personally, I like properties, but I just think of them as pretty methods 😉

Advertisements

Written by Tom

April 6, 2007 at 1:55 pm

Posted in .Net, C#, Optimization

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: