views:

328

answers:

7

I read somewhere that having public properties is preferable to having public members in a class.

  1. Is this only because of abstaraction and modularity? Are there any other over-riding reasons?

  2. The property accesses are conerted into function calls by the compiler. For properties without a backup store (e.g. public string UserName { get; set; }), what would be the performance overhead compared to a direct member access? (I know it shouldn't usually make a difference but in some of my code, properties are accessed millions of times.)

Edit1: I ran some test code over integer members and Properties and the public members were about 3-4 times as fast as Properties. (~57 ms. vs ~206 ms. in Debug and 57 vs. 97 in Release was the most common run value). For 10 million reads and writes, both are small enough not to justify changing anything.

Code:

    class TestTime1
{
    public TestTime1() { }
    public int id=0;
}
class TestTime2
{
    public TestTime2() { }
    [DefaultValue(0)]
    public int ID { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        try
        {
            TestTime1 time1 = new TestTime1();
            TestTime2 time2 = new TestTime2();
            Stopwatch watch1 = new Stopwatch();
            Stopwatch watch2 = new Stopwatch();
            watch2.Start();
            for (int i = 0; i < 10000000; i++)
            {
                time2.ID = i;
                i = time2.ID;
            }
            watch2.Stop();
            watch1.Start();
            for (int i = 0; i < 10000000; i++)
            {
                time1.id = i;
                i = time1.id;
            }
            watch1.Stop();
            Console.WriteLine("Time for 1 and 2 : {0},{1}",watch1.ElapsedMilliseconds,watch2.ElapsedMilliseconds);

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.In.ReadLine();
    }
}
+4  A: 

It is mostly for purposes of abstraction (you can later add validation without breaking existing code, or requiring recompilation).

Even when using auto-properties, there is still a backing field generated by the compiler, and will perform as such.

Rowland Shaw
+13  A: 

Don't worry at all about the performance overhead. It is so minor that you should not consider weakening the encapsulation of the class; it would be premature optimization of the worst sort.

Steven Sudit
+5  A: 

Is this only because of abstaraction and modularity? Are there any other over-riding reasons?

Not that I know of; these reasons are by themselves compelling enough. But maybe someone else will jump in on this.

The property accesses are conerted into function calls by the compiler. For properties without a backup store (e.g. public string UserName { get; set; }), what would be the performance overhead compared to a direct member access? (I know it shouldn't usually make a difference but in some of my code, properties are accessed millions of times.)

In the resulting Intermediate Language, a property access is translated to a method call. However, as the word says, this is only an Intermediate Language: it gets compiled Just-In-Time down to something else. This translation step also involves optimizations like inlining of trivial methods, such as simple property accessors.

I would expect (but you'd need to test to make sure) that the JITter takes care of such accessors, so there should be no performance difference.

Thomas
Here's one reason: .NET standards dictate that you must not expose a field as public, with very few exceptions. As for inlining, see my comment to Adam.
Steven Sudit
The standards dictate this for a reason, and I think it's that reason that we're looking for, not "because Microsoft says so" :)
Thomas
I would emphasize (eg boldify) the inlinging, as AFAIK that's the case with all properties on both Mono and the CLR.
Dykam
@Thomas: Yes, absolutely! I don't mean to suggest that this standard is arbitrary or counterproductive. I'm just saying that the very fact that it's a standard is itself a good reason, all things being (more or less) equal, to do it that way. Since performance considerations are inconsequential, I think that fuzzy ceteris paribus criterion is satisfied. :-)
Steven Sudit
@Dykam: I wouldn't, both because the speed difference is not significant compared to the loss of encapsulation, and because inlining is limited to cases where the caller is in the same assembly.
Steven Sudit
Here's a more authoritative answer (with links) on the issue of inlining: http://stackoverflow.com/questions/646779/does-c-inline-properties/646780#646780
Steven Sudit
+1  A: 

1) Its for encapsulation principles, but other .NET features use properties such as data binding.

2) I'm not sure I agree with that, I've always heard that if the property is a straight get/set its just as fast as a standard field access - the compiler does this for you.

Update: seems to be a bit of both, compiles to method call but JIT-optimized away. Either way, this sort of performance concern is not going to have a meaningful impact on your code. However, note that the guidance around implementing properties is to make them as light-weight as possible, they are not expected by callers to be expensive.

Adam
There are more details to this. I believe it can only inline the call when the caller and the property are defined in the same assembly, for example. But, really, it doesn't matter. The call overhead is nothing in comparison to what you gain from being able to replace an underlying field with as much logic as you need.
Steven Sudit
Strange, that's a rather odd detail for not inlining - disappointing in a way lol. As mentioned, the performance detrement, either compiled away or not, is negligible
Adam
Agreed regarding performance irrelevancy, but I think there's some sense to the limitation. When generating CIL code for the property call, the compiler needs to have access to the implementation so that it can confirm that there's just assignment to a backing variable and so that it can identify that variable. In other words, this optimization is part of the original compilation, not the final JIT one.
Steven Sudit
Ah yea, that does make sense.
Adam
At the risk of repeating myself, here's a link to a more authoritative answer: http://stackoverflow.com/questions/646779/does-c-inline-properties/646780#646780
Steven Sudit
A: 

After I posted this post, I realized that it's basically for hiding the inner workings of you object.

JSprang
+6  A: 

Running the test 20 times in a row, ensuring that JIT optimization is enabled in the Release build:

Time for 1 and 2 : 47,66
Time for 1 and 2 : 37,42
Time for 1 and 2 : 25,36
Time for 1 and 2 : 25,25
Time for 1 and 2 : 27,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 26,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25
Time for 1 and 2 : 25,25

Yes, the JITter is that good at inlining property accessors. Perf is a non-issue and should never be considered.

Hans Passant
+1 for putting it to the test.
Steven Sudit
Hmm... did the testing in debug instead of release. My bad!
apoorv020
In release, there's still a 80% overhead on my machine. My machine is 32-bit, I have seen some strange performance differences between 32-bit and 64-bit.
apoorv020
Mine is 32-bit as well, I assume we use the same JITter. Tools + Options, Debugging, General, uncheck "Suppress JIT optimization on module load".
Hans Passant
A: 

I've asked the same question before.

I'm guessing you're using VS2008, are using a 64-bit OS and have compilation set to "Any CPU"? If so, properties don't get inlined by the x64 JIT compiler. They do on 32-bit, making them identical in performance to public fields.

JulianR