punkouter wrote:
Hmmm... I'm not sure if the overhead even exists. I'm not exactly an expert on these, but I heard that .Net and Java JIT compiler optimizes codes. It might optimizes your code to
private bool IsSupported
{
get { return true; }
}
Sadly not. Reducing a statement like this requires inspection of the Version class (and the overloaded greater than operator), both of which are beyond the scope of the JIT compiler, whose primary purpose is to be
fast. If any optimisation like this were to be imposed, it could only be done at compile time, at which point you cannot treat the Environment.Version as constant.
On the plus side, there are people like me working on compilers that do crazy things to make your code go faster - for example, a call to the IsSupported function would be inlined.
punkouter wrote:
However, I heard that it's better to write clear code that reflects what you intent exactly (this return Environment.OSVersion.Version >= new Version(5,1);} version might be the best option) so that the JIT compiler can infer what you're trying to do and it may get better chances of being optimized.
You're absolutely right! It's
much more important for you to write good, maintainable code than it is for you to consider performance. It's up to the compiler developers (and to a lesser extent, the JIT) to optimise it.
For example, littleguru suggested above that (statement)? true : false was bad programming practise, and I would agree with him - it's harder to read and understand, but they will both compile to the same bytes, since the compiler automatically checks for well known programmer bugs such as the above.
Even Sven's problem of repeatably instantiating an object within a tight loop can be optimised if the constructor fulfills certain properties, and can be extracted to outside of the loop.
for an example, consider this fragment:
punkouter wrote:
List<String> a = new List<String> ();
for ( int i = 0; i< 10; i++ ) {
a.Clear();
a.Add( i.ToString() );
Debug.Write ( a [0] );
}
and
for ( int i = 0; i< 10; i++ ) {
List<String> a = new List<String> ();
a.Add ( i.ToString() );
Debug.Write ( a[0] );
}
(Not a very good sample, I know... but thats what I can think of right now)
If you're writing in C++, the first version will be the prefered way, but I read that if you're writing in .Net and Java, the second version is the prefered way. Because the list object is more closer to where it is being used, enclosed in the same scope and have a better chance of being optimized. (Note that I avoided using String because it's immutable in Java and .Net, so no real effect)
Actually in this case (which as you say isn't the best example) the first one is preferable in both cases. List<T> is difficult to optimise for a number of reasons, one of which being that it is completely different (although conceptually simmilar) to an array.
A better example would be:
string a = "";
for ( int i = 0; i< 10; i++ ) {
a = i.ToString();
Debug.Write ( a );
}
and
for ( int i = 0; i< 10; i++ ) {
string a = "";
a = i.ToString();
Debug.Write ( a );
}
In this case, C++ would definitely prefer the first option, and C# developers would prefer the second option.
By the way, when you mention that strings are immutable, that doesn't mean that they can't be replaced or generated. It only means that constructing a string literal can be done "for free", and that string operations are slightly more expensive than you'd expect - (("Hello" + "World") + "!") + "!" takes longer than "Hello" + ("World" + ("!" + "!")) and these all take longer than String.Concat("Hello","World","!","!");