Sign in to follow this  

C# Properties Cost

This topic is 4479 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was taught in my C# and C++ .NET classes that using get/set properties for private variables was the correct, and expected, method of allowing access to the various parts of a class object. One of my teachers explained that I would almost never allow direct access of a variable, and should use a property 99.9% of the time. I had some bottlenecks when working with very large object arrays that needed to constantly check various properties in an object: using the DXTimer and a very simple for loop test, I was able to see that it took around 75% more processing time to use a get/set property than to access the variable directly. So what is the positive trade here that makes such a sacrifice justified? Why were my teachers pushing the use of properties so hard when there is a huge cost? Will potential employers really see my code as "unprofessional"(as one teacher put it) if I have some of the heavily-accessed variables public with direct manipulation instead of using the get/set method?

Share this post


Link to post
Share on other sites
The advantage? Easily maintained code, that is also less vulnerable to changes in implementation.

The disadvantage? As you mentioned, performance loss in some cases, although I cannot help but wonder why the compiler wouldn't optimize trivial access to a variable.

Why is the sacrifice made? Because in most cases, it simply doesn't matter: if property access is 500% slower, but only represents 0.1% of actual time, you're still looking at a 0.5% increase in computation time only. Time spent refactoring private variables into properties when the need arises just because you wanted those 0.5% back is almost always better spent gaining another 5% from another area, such as adapting an algorithm to the statistical distribution of data.

I'd be quite interested in seeing the code in which properties caused a 75% increase in processing time by being the actual bottleneck.

Share this post


Link to post
Share on other sites
As ToohrVyk mentioned, using properties is to encapsulate the private parts. As first this might sound totally pointless, because accessing variables directly sounds better.

However, in some cases, you might want to turn certain variables into read-only from the outside, but read/write from the inside. Properties are usefull here.

However, what's more important is that in many cases, the property needs to do some work. For instance, you're making an RTS and you're changing a position of a unit on the map:


public MapCoordinate Location
{
get { return location; }
set
{
if (value.X < 0 || value.X > map.Width || value.Y < 0 || value.Y > map.Height)
{
// Uh oh, invalid position
throw new Exception("OMFGWTFBBQ");
}
location = value;
}
}


In here, there is some checking done in order to set the value. But in many cases, you develop a system, and later on you need features like that. Refactoring your code to refer to the property instead of the variable will take MUCH more time than doing it from the start.

Sure, you'll get some performance loss, but I doubt it'll be visible in the long term. And what's more important: If you're accessing a certain property A LOT, why not store it in a local variable?

Toolmaker

Share this post


Link to post
Share on other sites
Quote:
Original post by cyric74
I had some bottlenecks when working with very large object arrays that needed to constantly check various properties in an object: using the DXTimer and a very simple for loop test, I was able to see that it took around 75% more processing time to use a get/set property than to access the variable directly.


That sounds suspicious; trivial property getters should be inlined. Did you compile in release mode? Can you post the test code?

Share this post


Link to post
Share on other sites
ToohrVyk said it very well. But keep in mind that timing code execution is often quite inaccurate (that's what one of my professors told me!). You're never going to have the exact circumstances for each test case so the timed test will always be inaccurate (though often it's close enough). However, when you have such a noticable difference (75%!!), clearly you hit on something. I'm very surprised that you'd find such a difference with just using get/set functions.

Share this post


Link to post
Share on other sites
Quote:
Original post by cyric74
So what is the positive trade here that makes such a sacrifice justified? Why were my teachers pushing the use of properties so hard when there is a huge cost?

Before we start claiming that there is a "huge cost", I'd like to see the code you wrote that determines it cost 75% more time. In general, properties should be costing you almost no time in a release version.

Share this post


Link to post
Share on other sites
Just to make sure: Don't run in Debug mode. And by debug mode, I don't mean Debug vs. Release. I mean (assuming you're using visual studio) hit CTRL-F5 instead of F5. By hitting F5 you run the program in debug mode which allows visual studio to catch exceptions and interrupt control flow, which by necessity prevents the JIT from performing any optimizations. Hitting CTRL-F5 runs the program as a normal exe.

Share this post


Link to post
Share on other sites
If you have enough property accesses that they comprise 75% of the total processing time (debug mode or no debug mode), you might want to consider whether you have some misplaced responsibilities in your object model. If your app is well designed, such a cost shouldn't happen no matter how slow properties are.

Share this post


Link to post
Share on other sites
I was not aware of the impact that Debug mode had on this, and so I reran my test in release mode and had very different results (about 2% faster to use direct variable access). The problem I was having in my own code disappeared when I tested in release mode, so if anything I have much less to worry about than I originally thought. Thanks for the info!

Here was the test I was using:


class PropertySpeedTest
{
static void Main()
{
float TotalTime = 0;
SimpleClass simple = new SimpleClass();

DXUtil.Timer( DirectXTimer.GetElapsedTime );
for( int j = 0; j < 10000; j++ )
{
for( int i = 0; i < 1000000; i++ )
simple.X = i;
TotalTime += DXUtil.Timer( DirectXTimer.GetElapsedTime );
}
TotalTime = TotalTime / 10000;
System.Console.WriteLine( "Access Property: " + TotalTime );

TotalTime = 0;
DXUtil.Timer( DirectXTimer.GetElapsedTime );
for( int j = 0; j < 10000; j++ )
{
for( int i = 0; i < 1000000; i++ )
simple.Y = i;
TotalTime += DXUtil.Timer( DirectXTimer.GetElapsedTime );
}
TotalTime = TotalTime / 10000;
System.Console.WriteLine( "Access Variable: " + TotalTime );
}
}
public class SimpleClass
{
public SimpleClass()
{
X = 0;
Y = 0;
}
private int _X;
public int Y;

public int X
{
get{ return _X; }
set{ _X = value; }
}
}




Output:
Access Property: 0.000689111
Access Variable: 0.0006766411

Share this post


Link to post
Share on other sites
Benchmarking JIT compiled languages is rather problematic. How do you know your inner loop hasn't changed to: simple.Y = 1000000;
It might be better to have each benchmark in separate method, and call them in differnt orders. There might be different result if geter/setter benchmark would be called first.

Also, does simple.X = i; mean the same as setX(i), or is it a typo?

From what I dicovered when benchmarking Java. A getter access was twice faster than a.b access after all optimalizations were applied. 2x speed difference in such code isn't often big deal, so time waste by proper benchmark is often worse than possible slight speed slowdown.

Share this post


Link to post
Share on other sites

This topic is 4479 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this