tags:

views:

146

answers:

6

I have a class that has a public property. In a single function I refer to this property around 30-40 times.

  this.MyProp;

Would it be better to define a local variable in the function?,

 string myProp = this.MyProp;

After doing this - in the function I've shortened the lookup chains... so I only have to refer to myProp, rather than this.MyProp.

In JavaScript this shortening of lookups really improves performance. Would it be better / worse in C#? Because obviously, I've also needed to create another local string variable.

+11  A: 

From a pure performance perspective, it depends on what the property is doing. If the MyProp getter just returns a private field, the overhead is totally inconsequential. In fact, unless you're obviously doing something significant like some huge enumeration or calling into a database, it's of no concern. Worrying about this is micro-micro optimization.

It's important to note the purpose of properties though, which is to force access to a value through an encapsulated routine to ensure consistency. If you try to bypass that, you're exposing your code to greater risk for bugs.

From @DavidAndres comments:

According to convention, properties should typically not do anything substantial in the getter or setter. So I would say it's of no concern if you simply verify, via reflector or documentation or looking at your own code, that the property behaves well. Handling the situations where the value clearly does need to be localized should be an edge case, after it's been verified that it is necessary.

Edit: To be clear, I am not recommending you generally avoid local values for any performance reason. As @Guffa notes the impact is trivial either way. I am pointing out that properties are usually properties for a reason, and access to the value should go through the property by default.

Rex M
I also have another more complex scenario , where I have 3 complex objects, stored as properties in 1 object.... Would it be a good idea to localize these more complex objects?
JL
@JL no. Just use the properties.
Rex M
@Rex: I think it is of no concern if you're working with your own code, with full awareness of what properties are duoing "under-the-hood." If you're integrating third-party code into your libraries, then reducing property accesses may be a micro-optimization as opposed to a micro-micro-optimization, as you put it.
David Andres
@DavidAndres according to convention, properties should *typically* not do anything substantial in the getter or setter. So I would say it's of no concern if you simply verify, via reflector or documentation or looking at your own code, that the property behaves well.
Rex M
@DavidAndres handling the situations where the value clearly does need to be localized should be an edge case, after it's been verified that it is necessary.
Rex M
@Rex: Absolutely. Property getters should be fast in a well-designed system.
TrueWill
Well instead of just getter/setter, properties do some rules validation etc, imagin a loop with every access doing much of calculation which is not required !! Even architectures of CPU were built on concepts of caching, overall performance counts.
Akash Kava
@Akash performance only counts when there is a problem. If we haven't profiled and identified the property as a bottleneck, there is no problem yet.
Rex M
+1  A: 

Don't be afraid to declare local variables, it's almost free. On a 32 bit system the string variable will use four bytes of stack space. The stack frame where the local variables are allocated is always created, so it takes no extra execution time to allocate the variable.

However, whether you should use a local variable or not should rather be based on what's more correct in the situation. Unless you have a loop where you use the value something like a thousand times or more, the performance difference will hardly even be measurable.

(This is of course based on the assumption that the propery is properly implemented so that it isn't expensive to read.)

Guffa
A: 

I did performance calculation, however its tiny, but every tiny bits added can be a huge gain over cpu cycles as you are executing code 100s of times simulatenously in web server, in network activity etc.

C# Local Variable Caching Statistics, you can also download the code and play with it.

Akash Kava
-1 for micro-optimization. Profile your code. I sincerely doubt that you will find property access to be a bottleneck. I/O is usually the culprit.
TrueWill
You can't test this - it depends entirely on what the property get actually does
annakata
Profileing will not guess what the property is actually doing, you are right in your answer that if property is not really calculating something large everytime its micro micro optimization but you call 100s of properties whose internals you dont know !! How do you make sure?
Akash Kava
@Akash make sure by using Reflector, or use a tool like RedGate Profiler to see if the call to the property is causing a performance bottleneck.
Rex M
@Rex M, for every properties I call? for every internal functions it calls? I think its too much to do rather then just following correct practice.
Akash Kava
@Rex M, I have seen people using config values by direct access, look at the results on my site, imagin 1000s of users logged on to server, executing 1000s of web application code, well the code is very small, this is what a human brain can do which no profiler or automated testing tools can think, thats why humans can still think better then machines.
Akash Kava
I know that reality may differ here, but people should not be writing properties that perform large calculations anyway. It is misleading. If you need to perform some intensive calculation, use a method.
Ed Swangren
I just made a test between reading a parameter returning the value of a variable and reading the variable itself, and there is no performance difference at all.
Guffa
A: 

You normally don't need "this." to refer to a property or field in the same class. I only use it if there's a naming conflict. Microsoft's naming guidelines avoid the conflicts, so I don't use it. :)

As an aside, if you have a single method that refers to a property 30-40 times, it's likely that you have a Long Method smell.

EDIT: I didn't intend to start a religious war over the use of "this." (See Do you prefix your instance variable with ‘this’ in java ?) In our company we prefix fields with underscores (which is another hot topic); that plus our (otherwise non-Hungarian) naming conventions makes it very obvious which are properties. With ReSharper, we can even do things like color-code parameters differently. Personally I find "this" to be noise, and follow ReSharper's suggestions to remove it.

In the end I stand by my answer. While I value readability highly, if you can't quickly and easily determine what a method is doing (this or no this), it's probably too long.

TrueWill
Its true you don't need to use this.... but its a better practice, because other people reading your code (and yourself) can see that the property is a member of the class (in one glance), not sure if there are any compiler benefits from this - but I always use this... for properties or fields of the class...
JL
There are no compiler benefits but clarity is everything.
annakata
And I mean THIS... not this (question) ... in case there is any confusion...
JL
Agree with JL - using `this` rarely, if ever, hurts code clarity.
Rex M
A: 

For a simple function and regular properties this shouldn't worry you at all.
This does seem like a good question for lambda expressions though, and a quick test shows it might be worth while on that case, if you have a lot of references to properties (this is similar to what was done here):

class Program
{
    public static int Property { get; set; }

    static void Main(string[] args)
    {
        Property = 3;
        int mainVar = Property;

        for (int run = 0; run < 5; run++)
        {
            Stopwatch s = new Stopwatch();
            Action useProperty = () =>
            {
                double res;
                for (int counter = 0; counter < 10000000; counter++)
                    res = Math.Cos(Property);
            };
            s.Start();
            useProperty();
            Console.WriteLine("Property Direct   : {0}", s.Elapsed);
            s.Reset();

            Action useMainVar = () =>
            {
                double res;
                for (int counter = 0; counter < 10000000; counter++)
                    res = Math.Cos(mainVar);
            };
            s.Start();
            useProperty();
            Console.WriteLine("Variable from Main: {0}", s.Elapsed);
            s.Reset();

            Action useLocalVariable = () =>
            {
                int j = Property;
                double res;
                for (int counter = 0; counter < 10000000; counter++)
                    res = Math.Cos(j);
            };
            s.Start();
            useLocalVariable();
            Console.WriteLine("Lambda Local      : {0}", s.Elapsed);
            Console.WriteLine();
        }
        Console.ReadKey();
    }
}

Result:

Property Direct   : 00:00:00.6410370
Variable from Main: 00:00:00.6265704
Lambda Local      : 00:00:00.2793338

Property Direct   : 00:00:00.6380671
Variable from Main: 00:00:00.6354271
Lambda Local      : 00:00:00.2798229

Property Direct   : 00:00:00.6337640
Variable from Main: 00:00:00.6280359
Lambda Local      : 00:00:00.2809130

Property Direct   : 00:00:00.6286821
Variable from Main: 00:00:00.6254493
Lambda Local      : 00:00:00.2813175

Property Direct   : 00:00:00.6279096
Variable from Main: 00:00:00.6282695
Lambda Local      : 00:00:00.2783485
Kobi
A: 

Most smaller properties are getting automatically inlined by the JIT, so not much performance gain for that.

For non-trivial properties you will indeed save time when shortening lookup chains. The optimizer is not allowed to remove redundant calls because it cannot determine whether they have side effects or not, otherwise it would change the program's semantics.

There is one exception where you should not save a property value into a local:

for (int i=0; i<myArray.Length; i++) { /* do something with myArray[i] */ }

This pattern is recognized by the JIT and it will automatically remove the array access bounds test.

But if you do this:

int len = myArray.Length;
for (int i=0; i<len; i++) { /* do something with myArray[i] */ }

Then the bounds test cannot be removed since the optimizer can never be sure if the variable len could be tempered with.

So think twice before you "optimize".

codymanix