Muzaffer
Muzaffer

Reputation: 306

C# - Accessing object variable

I would like to know best way in terms of performance to consume object value. I have seen the code where values are cached and used in later part.It looks clean in terms of usage. Performance wise which is better and why. This might be simple question but I am sure many of would like to know the answer.

Below is the sample code.

//Class with variables
Cls A
{   
   String a = "aaa";
   String b = "bbb"; 
   String c = "ccc";  
}

//Cls B with Cls A object and initialized
Cls B
{  
  A a1 = new A(); 
}

**One**
B b1 = new B();
Str t1 = b1.a1.a;
Str t2 = b1.a1.b;

**Two**
B b1 = new B();
A c1 = b1.a1;
Str t1 = c1.a;
Str t2 = c1.b;

Will stack or heap come into play

Upvotes: 0

Views: 3110

Answers (2)

Hayden
Hayden

Reputation: 2988

For this a good old benchmark can quantitatively give you what you want.

Testing methodology

class A {
    public string a = "aaa", b = "bbb", c = "ccc";
}

class B {
    public A a1 = new A();
}

class Program {
    static void Main(string[] args) {

        int counter = 0;
        int counter2 = 0;

        Stopwatch sw = new Stopwatch();

        // Method 1
        sw.Start();

        B b1 = new B();
        while (sw.ElapsedMilliseconds < 5000) {
            string t1 = b1.a1.a;
            string t2 = b1.a1.b;
            counter++;
        }

        sw.Stop();
        sw.Reset();

        // Method 2
        sw.Start();

        B b2 = new B();
        A c1 = b2.a1;
        while (sw.ElapsedMilliseconds <5000) {
            string t3 = c1.a;
            string t4 = c1.b;
            counter2++;
        }

        sw.Stop();

        Console.WriteLine("Counter={0}", counter);
        Console.WriteLine("Counter2={0}", counter2);
        Console.ReadKey();
    }
}

I test both methods for 5 seconds assigning values to the properties.

Note: this could of been designed better, but this will still give us reasonably accurate results.

After 5 runs at this, here are the results:

Output (Note: The higher the better as we measuring which method has a higher number of executions)

Counter=33054729
Counter2=33783643

Counter=32599924
Counter2=33610612

Counter=52581701
Counter2=53822872

Counter=50725227
Counter2=51932970

Counter=32688454
Counter2=32577850

As you can see, the results are relatively close, but the second method overall seems to be faster. A possible explanation could be the overhead cost of calling a method within a property. If anyone else could provide a better explanation, let me know.

Upvotes: 0

xanatos
xanatos

Reputation: 111940

In this specific case they are probably equivalent, because a1 is a field.

In general if a1 is a property you could not know how it's "backed" (where it saves the value).

If it saves its value on a field then accessing the property is nearly/as fast as caching its value. If it has to calculate its value every time/has to access a Dictionary/other complex object then it could be better to cache it.

In ASP.NET often a1 could be a Session[...]/ViewState[...] objects (they are like Dictionary in the end, so they work in a similar way speed-wise), so if you access it in a tight for or while cycle sometimes it could be better to "cache" its value.

In general this is premature optimization. You don't do it unless you need it.

To give some classic example:

public class MyClass {
    // A field
    public int Fast1;

    // An automatic property backed by a field
    public int Fast2 { get; set; }

    // A property backed by a field
    public int Fast3 {
        get { return Fast1; }
    }

    // Each time you call this property, some calculation is done
    public int LittleSlow1 {
        get {
            int j = 0;
            for (int i = 0; i < 1000000; i++) {
                if (i > j) {
                    i = j;
                }
            }
            return j;
        }
    }

    // This property is backed by a collection. There is a
    // scan of the collection to retrieve the value.
    public int LittleSlow2 {
        get {
            return ignoreme["LittleSlow1"];
        }
    }

    public Dictionary<string, int> ignoreme = new Dictionary<string, int>();
}

One of the reasoning against properties is that they are nearly identical to fields in the way you use them like myprop = 5 or x = myprop + 1, but for that way they "hide" to the programmer the potential cost of using them, while when a programmer calls a method he knows that the method could be expensive.

Upvotes: 1

Related Questions