Why are public fields faster than properties? - c#

I was poking around in XNA and saw that the Vector3 class in it was using public fields instead of properties. I tried a quick benchmark and found that, for a struct the difference is quite dramatic (adding two Vectors together a 100 million times took 2.0s with properties and 1.4s with fields). For a reference type, the difference doesn't seem to be that large but it is there.
So why is that? I know that a property is compiled into get_X and set_X methods, which would incur a method call overhead. However, don't these simple getters/setters always get in-lined by the JIT? I know you can't guarantee what the JIT decides to do, but surely this is fairly high on the list of probability? What else is there that separates a public field from a property at the machine level?
And one thing I've been wondering: how is an auto-implemented property (public int Foo { get; set; }) 'better' OO-design than a public field? Or better said: how are those two different? I know that making it a property is easier with reflection, but anything else? I bet the answer to both questions is the same thing.
BTW: I am using .NET 3.5 SP1 which I believe fixed issues where methods with structs (or methods of structs, I'm not sure) weren't in-lined, so that isn't it. I think I am using it at least, it's certainly installed but then again, I'm using Vista 64-bit with SP1 which should have DX10.1 except that I don't have DX10.1 ..
Also: yeah, I've been running a release build :)
EDIT: I appreciate the quick answers guys, but I indicated that I do know that a property access is a method call, but that I don't know why the, presumably, in-lined method is slower than a direct field access.
EDIT 2: So I created another struct that used explicit GetX() methods (o how I don't miss my Java days at all) and that performed the same whether I disabled in-lining on it (through [MethodImplAttribute(MethodImplOptions.NoInlining)]) or not, so conclusion: non-static methods are apparently never inlined, not even on structs.
I thought that there were exceptions, where the JIT could optmize the virtual method call away. Why can't this happen on structs which know no inheritance and thus a method call can only point to one possible method, right? Or is that because you can implement an interface on it?
This is kind of a shame, since it will really make me think about using properties on performance critical stuff, yet using fields makes me feel dirty and I might as well write what I'm doing in C.
EDIT 3: I found this posting about the exact same subject. His end conclusion is that the property call did get optimized away. I also could've sworn that I've read plenty of times that simple getter/setter properties will get in-lined, despite being callvirt in the IL. So am I going insane?
EDIT 4: Reed Copsey posted the answer in a comment below:
Re: Edit3 - see my updated comment: I believe this is x86 JIT vs x64 JIT issues. the JIT in x64 is not as mature. I'd expect MS to improve this quickly as more 64 bit systems are coming online every day. – Reed Copsey
And my response to his answer:
Thanks, this is the answer! I tried forcing a x86 build and all methods are equally fast, and much faster than the x64. This is very shocking to me actually, I had no idea I was living in the stone age on my 64-bit OS.. I'll include your comment in my answer so it stands out better. – JulianR
Thanks everyone!

Edit 2:
I had another potential thought here:
You mentioned that you are running on x64. I've tested this same issue on x86, and seen the same performance when using auto-properties vs. fields. However, if you look around on Connect and mailing list/forum posts, there are many references online to the fact that the x64 CLR's JIT is a different code base, and has very different performance characteristics to the x86 JIT. My guess is this is one place where x64 is still lagging behind.
Also, FYI, the struct/method/etc thing fixed in .net 3.5sp1 was on the x86 side, and was the fact that method calls that took structs as a parameter would never be inlined on x86 prior to .net3.5sp1. That's pretty much irrelevant to this discussion on your system.
Edit 3:
Another thing: As to why XNA is using fields. I actually was at the Game Fest where they announced XNA. Rico Mariani gave a talk where he brought up many of the same points that are on his blog. It seems the XNA folks had similar ideas when they developed some of the core objects. See:
http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx
Particularly, check out point #2.
As for why automatic properties are better than public fields:
They allow you to change the implementation in v2 of your class, and add logic into the property get/set routines as needed, without changing your interface to your end users. This can have a profound effect on your ability to maintain your library and code over time.
---- From original post - but discovered this wasn't the issue--------
Were you running a release build outside of VS? That can be one explanation for why things aren't being optimized. Often, if you are running in VS, even an optimized release build, the VS host process disables many functions of the JIT. This can cause performance benchmarks to change.

You should read this article by Vance. It goes into detail about why methods are not always inlined by the JIT'er even if it looks completely obvious that they should be.
http://blogs.msdn.com/vancem/archive/2008/08/19/to-inline-or-not-to-inline-that-is-the-question.aspx

Public fields are direct assignments
Properties are methods, then more code, insignificant but more.

XNA has to target the XBox 360, and the JIT in the .NET Compact Framework isn't as sophisticated as its desktop counterpart. The .NET CF JIT'er won't inline property methods.

Accessing a field is just a memory reference whereas using a property is actually invoking a method and includes the function call overhead. The reason to use properties rather than fields is to insulate your code from changes and provide better granularity over access. By not exposing your field directly you have greater control over how the access is done. Using automatic fields allows you to get the typically getter/setter behavior but builds in the ability to change this without a subsequent need for the changes to propagate to other parts of the code.
For example, say that you want to change your code so that access to a field is controlled by the current user's role. If you had exposed the field publicly, you'd have to touch every part of the code that accessed it. Exposing it through a property allows you to modify the property code to add your new requirement but doesn't result in unnecessary changes to any code that accesses it.

Related

Are there significant performance gains inherent in using .NET's built in classes?

Quick little question...
I know that sometimes in other languages libraries have part of their code written in platform-specific straight C for performance reasons. In such cases you can get huge performance gains by using library code wherever possible.
So does the .NET platform do this? Is Microsoft's implementation of the Base Class Library optimized in some way that I can't hope to match in managed code?
What about something little like using KeyValuePair as a type-safe tuple struct instead of writing my own?
As far as I know, the .NET Framework hasn't been compiled in a way that creates hooks into some otherwise-inaccessible hardware acceleration or something like that, so for simple things like KeyValuePair and Tuple, you're probably safe rolling your own.
However, there are a number of other advantages to using standard framework classes, and I'd hesitate to write my own without a strong reason.
They're already written, so why give yourself extra work?
Microsoft has put their code through a pretty rigorous vetting process, so there's a good chance that their code will be more correct and more efficient than yours will.
Other developers that have to look at your code will know exactly what to expect when they see standard framework classes being used, whereas your home-brewed stuff might make them scratch their heads for a while.
Update
#gordy also makes a good point, that the standard framework classes are being used by everybody and their dog, so there will be a slight performance gain simply due to the fact that:
the class likely won't have to be statically instantiated or just-in-time compiled just for your code,
the class's instructions are more likely to already be loaded in a cache, since they'll likely have been used recently by other parts of code. By using them, you're less likely to need to load the code into a cache in the first place, and you're less likely to be kicking other code out of the cache that's likely to be used again soon.
I've wondered this myself but I suspect that it's not the case since you can "decompile" all of base libraries in Reflector.
There's probably still a performance advantage over homemade stuff in that the code is likely jitted already and cached.
I suggest you use built-in classes most of the time, UNLESS YOU'VE MEASURED IT'S NOT FAST ENOUGH.
I'm pretty sure MS put a lot of time and effort building something fast and reliable. It is totally possible you can beat them... after a few weeks of efforts. I just don't think it is worth the time most of the time.
The only time it seems ok to rewrite something is when it does not do all that you want. Just be aware of the time cost and the associated difficulty.
Could you ever hope to match the performance? Possibly, though keep in mind their code has been fully tested and extremely optimized, so I'd say it's not a worth-while effort unless you have a very specific need that there isn't a BCL type that directly fulfills.
And .NET 4.0 already has a good Tuple<> implementation. Though in previous versions of .NET you'd have to roll your own if you need anything bigger than a KeyValuePair.
The real performance gain comes from the fact that the MS team built and tested the library methods. You can rest assured with a very high degree of comfort that the objects will behave without introducing bugs.
Then there is the matter of re-inventing the wheel. You'd really have to have a great reason for doing so.
Main performance reasons always lay in architecture or complex algorithms, language is no matter.
Miscrosoft Base Class Library always comes with a complexity explanation for "heavy" methods. So you can easily decide use it, or find another "faster" algorithm to implement or use.
Of corse when it comes to heavy algorithms (graphics, archiving, etc.) then performance gains from going to lower level language come in handy.

Why did the BeforeFieldInit behavior change in .NET 4?

In C# 4, the behavior of types without the beforefieldinit flag was changed, so now a type initializer can call before first use of any static field of the class.
My questions are why has the C#/.NET team changed that behavior? What is the main reason? Can you show any practical example where this change makes any sense?
The behaviour has always been within the bounds of what's documented - it's just that it changed from being eager to lazy in .NET 4.
I suspect the JIT team managed to find a way to make it lazy without a performance penalty... or possibly it helps performance somewhere else. This is likely to only be one such change in behaviour within the .NET 4 CLR vs the .NET 2 CLR... it happens that I noticed it, but I doubt that many other people did. I think it's entirely reasonable for the JIT team to adjust things as they see fit, within the documented guarantees.
Ultimately, if this makes your code fail, you've got a bug already.

Is there any reason C# does not support manual inline methods? And what about optional parameters?

Is there any design reason for that (like the reason they gave up multi inheritance)?
or it just wasn't important enough?
And same question applies for optional parameters in methods... this was already in the first version of vb.net... so it surely no laziness that cause MS not to allow optional parameters, probably architecture decision.. and it seems they had change of heart about that, because C# 4 is going to include that..
What was the decision and why did they give it up?
Edit:
Maybe readers didn't fully understand me. I'm working lately on a calculation program (support numbers of any size, to the last digit), in which some methods are used millions of times per second.
Say I have a method called Add(int num), and this method is used quiet a lot with 1 as parameter (Add(1);), I've found out it is faster to implement a special method especially for one. And I don't mean overloading - Writing a new method called AddOne, and literally copy the Add method into it, except that instead of using num I'm writing 1. This might seems horribly weird to you, but it's actually faster.
(as much as ugly it is)
That made me wonder why C# doesn't support manual inline which can be amazingly helpful here.
Edit 2:
I asked myself whether or not to add this. I'm very well familiar with the weirdness (and disadvantages) of choosing a platform such as dot net for such project, but I think dot net optimizations are more important than you think... especially features such as Any CPU etc.
To answer part of your question, see Eric Gunnerson's blog post: Why doesn't C# have an 'inline' keyword?
A quote from his post:
For C#, inlining happens at the JIT
level, and the JIT generally makes a
decent decision.
EDIT: I'm not sure of the reason for delayed optional parameters support, however saying they "gave up" on it sounds as though they were expected to implement it based on our expectations of what other languages offered. I imagine it wasn't high on their priority list and they had deadlines to get certain features out the door for each version. It probably didn't rise in importance till now, especially since method overloading was an available alternative. Meanwhile we got generics (2.0), and the features that make LINQ possible etc. (3.0). I'm happy with the progression of the language; the aforementioned features are more important to me than getting support for optional parameters early on.
Manual inlining would be almost useless. The JIT compiler inlines methods during native code compilation where appropriate, and I think in almost all cases the JIT compiler is better at guessing when it is appropriate than the programmer.
As for optional parameters, I don't know why they weren't there in previous versions. That said, I don't like them to be there in C# 4, because I consider them somewhat harmful because the parameter get baked into the consuming assembly and you have to recompile it if you change the standard values in a DLL and want the consuming assembly to use the new ones.
EDIT:
Some additional information about inlining. Although you cannot force the JIT compiler to inline a method call, you can force it to NOT inline a method call. For this, you use the System.Runtime.CompilerServices.MethodImplAttribute, like so:
internal static class MyClass
{
[System.Runtime.CompilerServices.MethodImplAttribute(MethodImplOptions.NoInlining)]
private static void MyMethod()
{
//Powerful, magical code
}
//Other code
}
My educated guess: the reason earlier versions of C# didn't have optional parameters is because of bad experiences with them in C++. On the surface, they look straight-forward enough, but there are a few bothersome corner cases. I think one of Herb Sutter's books describes this in more detail; in general, it has to do with overriding virtual methods. Maximilian has mentioned one of the .NET corner cases in his answer.
You can also pretty much get by with out them by manually writing multiple overloads; that may not be very nice for the author of the class, but clients will hardly notice the difference between overloads and optional parameters.
So after all these years w/o them, why did C# 4.0 add them? 1) improved parity with VB.NET, and 2) easier interop with COM.
I'm working lately on a calculation program (support numbers of any size, to the last digit), in which some methods are used literally millions of times per second.
Then you chose a wrong language. I assume you actually profiled your code (right?) and know that there is nothing apart from micro-optimisations that can help you. Also, you're using a high-performance native bigint library and not writing your own, right?
If that's true, don't use .NET. If you think you can gain speed on partial specialisation, go to Haskell, C, Fortran or any other language that either does it automatically, or can expose inlining to you to do it by hand.
If Add(1) really matters to you, heap allocations will matter too.
However, you should really look at what the profiler can tell you...
C# has added them in 4.0: http://msdn.microsoft.com/en-us/library/dd264739(VS.100).aspx
As to why they weren't done from the beginning, its most likely because they felt method overloads gave more flexibility. With overloading you can specify multiple 'defaults' based on the other parameters that you're taking. Its also not that much more syntax.
Even in languages like C++, inlining something doesn't guarantee that it'll happen; it's a hint to the compiler. The compiler can either take the hint, or do its own thing.
C# is another step removed from the generated assembly code (via IL + the JIT), so it becomes even harder to guarantee that something will inline. Furthermore, you have issues like the x86 + x64 implementations of the JIT differing in behaviour.
Java doesn't include an inline keyword either. The better Java JITs can inline even virtual methods, nor does the use of keywords like private or final make any difference (it used to, but that is now ancient history).

Surprises Moving from C++ to C#

I am a C++ programmer moving into C#. I worked with the language for a month now and understand many concepts.
What are some surprises I may get while moving from C++ to C#? I was warned about destructors not being executed as I intended. Recently I tried to do something with generics that would use T as the base class. That didn't work. I also had another problem but I'll chalk that up to inexperience in C#. I was also surprised that my app was eating RAM, then I figured out I needed to use .dispose in one function. (I thought it would clean up like a smart pointer)
What else may surprise me?
Please no language bashing. I doubt anyone will but just in case...
Fortunately, Microsoft have some of that info here: C# for C++ Developers.
The struct vs class differences is another biggie for C++ origins.
I think you've covered the main one. You should read up on garbage collection, understand why there are no destructors as such, figure out the IDisposable pattern (which kind of replaces destructors). I'd say that was the big one.
The only other thing I would say is to warn you the C# and the .Net Base Class Library are pretty big, to get the most out of it there is a lot to learn... Once you have covered the basics of garbage collection and the type system you'll want to look at LINQ, and you should take the time to explore the relevnt libraries / frameworks for your area (e.g. WPF, WCF, ASP.Net etc). But it's all good. I moved from C++ to C# and would never go back, I find it way more productive (I'm not bashing C++, I do still dable:-) )
Well, the languages are completely different as I'm sure you've realized if you've worked with C# for any time. You don't have a powerful macro or templating (I realize there are generics in C#) in C# as you do in C++. As far as memory, remember you aren't in a tightly controlled environment anymore. Expect to see a lot of memory usage in Task Manager and similar tools, this is normal. There are better, more fine-grained performance counters to see true memory usage. Also, you probably don't need to call dispose as much as you might think (by the way, check out "using" blocks if you haven't already).
Another clear one is the default constructor, in C# this does not create a new Foo object:
Foo myFoo;
You can't have anything like a "void pointer" unless you just think of that as being like having a reference of type object. As well, you need to think of Properties as syntactic sugar for methods and not public members as they look in C++ syntax.
Make sure you understand "out" and "ref" parameters.
Obviously this not a large list, just a few "pointers" (no pun intended).
This is a rather big topic. A few thoughts:
C# is garbage collected. Doesn't mean you can stop paying attention about resource allocation, but in general you don't have to worry nearly as much about the most common resource: memory.
In C# Everything is an object. There are no "primitive" datatypes, even an int is an object.
C# has generics, not templates. Templates are far richer and more complex than C#'s similarly syntaxed generics, but generics still provide nearly all of the practical utility of templates, without many of the headaches.
C# has interfaces and single inheritance. Where you might look to multiple inheritance in C++, instead look to using interfaces or a different design pattern (e.g. strategy).
C# has delegates instead of function pointers. A delegate is basically just a typed function pointer. The use of delegates and delegate-relatives (lambda expressions, events, predicates, etc.) is very powerful and worth putting significant effort into studying.
C# supports yield return. This is very fundamental to the C# way of doing things. The most common form of iterating over some set is to use foreach. It's worth understanding how IEnumerable and iterators work.
I've made pretty much the same change some months ago (before that I've made a change to Java - but I didn't really spend much time programming Java).
Here are some of the biggest traps I've come across:
Attribute vs. Variable vs. Setter
One of the biggest traps I was stepping into was knowing if you have to change an attribute or set a variable or use a setter to set some aspect of a class.
IList vs. List vs. other collections
Know the difference between IList, List and all the other collections (IMO you can't really do much with an IList).
Generics do have their own pitfalls
And if you plan to use a lot of generics, maybe reading this helps you avoiding some of my errors:
Check if a class is derived from a generic class
But in general I'd say that the change went pretty painlessly.
Differences in the object model. For example value and reference types are separate by definition, not by how they are instantiated. This has some surprises, e.g.
myWinForm.Size.Width = 100;
will not change the width, you need to create a new Size instance and assign it.
Some things that I have not seen mentioned that are not available in C++ and may be a bit surprising are attributes and reflection
Attributes as such do not give you full fledged AOP. However, they do allow you to solve a bunch of problems in a way that is very different to how you would solve them in C++.

How costly is .NET reflection?

I constantly hear how bad reflection is to use. While I generally avoid reflection and rarely find situations where it is impossible to solve my problem without it, I was wondering...
For those who have used reflection in applications, have you measured performance hits and, is it really so bad?
In his talk The Performance of Everyday Things, Jeff Richter shows that calling a method by reflection is about 1000 times slower than calling it normally.
Jeff's tip: if you need to call the method multiple times, use reflection once to find it, then assign it to a delegate, and then call the delegate.
It is. But that depends on what you're trying to do.
I use reflection to dynamically load assemblies (plugins) and its performance "penalty" is not a problem, since the operation is something I do during startup of the application.
However, if you're reflecting inside a series of nested loops with reflection calls on each, I'd say you should revisit your code :)
For "a couple of time" operations, reflection is perfectly acceptable and you won't notice any delay or problem with it. It's a very powerful mechanism and it is even used by .NET, so I don't see why you shouldn't give it a try.
Reflection performance will depend on the implementation (repetitive calls should be cached eg: entity.GetType().GetProperty("PropName")). Since most of the reflection I see on a day to day basis is used to populate entities from data readers or other repository type structures I decided to benchmark performance specifically on reflection when it is used to get or set an objects properties.
I devised a test which I think is fair since it caches all the repeating calls and only times the actual SetValue or GetValue call. All the source code for the performance test is in bitbucket at: https://bitbucket.org/grenade/accessortest. Scrutiny is welcome and encouraged.
The conclusion I have come to is that it isn't practical and doesn't provide noticeable performance improvements to remove reflection in a data access layer that is returning less than 100,000 rows at a time when the reflection implementation is done well.
The graph above demonstrates the output of my little benchmark and shows that mechanisms that outperform reflection, only do so noticeably after the 100,000 cycles mark. Most DALs only return several hundred or perhaps thousands of rows at a time and at these levels reflection performs just fine.
If you're not in a loop, don't worry about it.
Not massively. I've never had an issue with it in desktop development unless, as Martin states, you're using it in a silly location. I've heard a lot of people have utterly irrational fears about its performance in desktop development.
In the Compact Framework (which I'm usually in) though, it's pretty much anathema and should be avoided like the plague in most cases. I can still get away with using it infrequently, but I have to be really careful with its application which is way less fun. :(
My most pertinent experience was writing code to compare any two data entities of the same type in a large object model property-wise. Got it working, tried it, ran like a dog, obviously.
I was despondent, then overnight realised that wihout changing the logic, I could use the same algorithm to auto-generate methods for doing the comparison but statically accessing the properties. It took no time at all to adapt the code for this purpose and I had the ability to do deep property-wise comparison of entities with static code that could be updated at the click of a button whenever the object model changed.
My point being: In conversations with colleagues since I have several times pointed out that their use of reflection could be to autogenerate code to compile rather than perform runtime operations and this is often worth considering.
It's bad enough that you have to be worried even about reflection done internally by the .NET libraries for performance-critical code.
The following example is obsolete - true at the time (2008), but long ago fixed in more recent CLR versions. Reflection in general is still a somewhat costly thing, though!
Case in point: You should never use a member declared as "Object" in a lock (C#) / SyncLock (VB.NET) statement in high-performance code. Why? Because the CLR can't lock on a value type, which means that it has to do a run-time reflection type check to see whether or not your Object is actually a value type instead of a reference type.
As with all things in programming you have to balance performance cost with with any benefit gained. Reflection is an invaluable tool when used with care. I created a O/R mapping library in C# which used reflection to do the bindings. This worked fantastically well. Most of the reflection code was only executed once, so any performance hit was quite small, but the benefits were great. If I were writing a new fandangled sorting algorithm, I would probably not use reflection, since it would probably scale poorly.
I appreciate that I haven't exactly answered your question here. My point is that it doesn't really matter. Use reflection where appropriate. It's just another language feature that you need to learn how and when to use.
Reflection can have noticeable impact on performance if you use it for frequent object creation. I've developed application based on Composite UI Application Block which is relying on reflection heavily. There was a noticeable performance degradation related with objects creation via reflection.
However in most cases there are no problems with reflection usage. If your only need is to inspect some assembly I would recommend Mono.Cecil which is very lightweight and fast
Reflection is costly because of the many checks the runtime must make whenever you make a request for a method that matches a list of parameters. Somewhere deep inside, code exists that loops over all methods for a type, verifies its visibility, checks the return type and also checks the type of each and every parameter. All of this stuff costs time.
When you execute that method internally theres some code that does stuff like checking you passed a compatible list of parameters before executing the actual target method.
If possible it is always recommended that one caches the method handle if one is going to continually reuse it in the future. Like all good programming tips, it often makes sense to avoid repeating oneself. In this case it would be wasteful to continually lookup the method with certain parameters and then execute it each and everytime.
Poke around the source and take a look at whats being done.
As with everything, it's all about assessing the situation. In DotNetNuke there's a fairly core component called FillObject that uses reflection to populate objects from datarows.
This is a fairly common scenario and there's an article on MSDN, Using Reflection to Bind Business Objects to ASP.NET Form Controls that covers the performance issues.
Performance aside, one thing I don't like about using reflection in that particular scenario is that it tends to reduce the ability to understand the code at a quick glance which for me doesn't seem worth the effort when you consider you also lose compile time safety as opposed to strongly typed datasets or something like LINQ to SQL.
Reflection does not drastically slow the performance of your app. You may be able to do certain things quicker by not using reflection, but if Reflection is the easiest way to achieve some functionality, then use it. You can always refactor you code away from Reflection if it becomes a perf problem.
I think you will find that the answer is, it depends. It's not a big deal if you want to put it in your task-list application. It is a big deal if you want to put it in Facebook's persistence library.

Categories

Resources