views:

79

answers:

6

From a post-compilation perspective (rather than a coding syntax perspective), in C#, is there any actual difference in the compiled code between a set of operations that have occurred on one line to a set of operations that occur across multiple lines?

This

object anObject = new object();
anObject = this.FindName("rec"+keyPlayed.ToString());
Rectangle aRectangle = new Rectangle();
aRectangle = (Rectangle)anObject;

vs this.

Rectangle aRectangle = (Rectangle)this.FindName("rec"+keyPlayed.ToString());

I wonder because there seems to be a view that the least amount of lines used is better however I would like to understand if this is because there is a tangible technical benefit or if there was at some point a tangible benefit or if it is indeed for a reason that is quantifiable?

+9  A: 

The number of lines don't matter; the IL will be identical if the code is equivalent (your's isn't).

And actually, unless we know what FindName returns, we can't answer properly - since by casting to object you might be introducing a "box" operation, and you might be changing a conversion operation (or perhaps a passive no-op cast) into an active double-cast (cast to object, cast to Rectangle). For now, I'll assume that FindName returns object, for simplicity. If you'd used var, we'd know at a glance that your code wasn't changing the type (box / cast / etc):

var anObject = this.FindName("rec"+keyPlayed.ToString());

In release mode (with optimize enabled) the compiler will remove most variables that are set and then used immediately. The biggest difference between the two lines above is that the second version doesn't create and discard new object() and new Rectangle(). But if you hadn't have done that, the code would have been equivalent (again, assuming that FindName returns object):

object anObject;
anObject = this.FindName("rec"+keyPlayed.ToString());
Rectangle aRectangle;
aRectangle = (Rectangle)anObject;

Some subtleties exist if you re-use the variable (in which case it can't necessarily be removed by the compiler), and if that variable is "captured" by a lambda/anon-method, or used in a ref/out. And some more subtleties for some math scenarios if the compiler/JIT chooses to do an operation purely in the registers without copying it back down to a variable (the registers have different (greater) width, even for "fixed-size" math like float).

Marc Gravell
+1  A: 

The compiled code may not have any difference (with optimization enabled perhaps), but think about readability too :)

In your example, everything on one line is actually more readable than separate lines. What you were trying to do was immediately obvious there. But others can quickly point out counter-examples. So use your good judgment to decide which way to go.

+1  A: 

There's a refactoring pattern to prefer a call to a temporary variable. Following this pattern reduces the number of lines of code but makes interactive debugging harder.

sharptooth
+2  A: 

I think that you should generally aim to make your code as readable as possible, and sometimes that means seperating out your code and sometimes it means having it on one line. Aim for readablity and if performance becomes a problem, use profiling tools to analyse the code and refactor it if necessary.

Charlie
+1 Totally agree with this. Its the cost of maintaining code not of writing it first time that's expensive. Any that makes it easier for others reading your code is a good thing.
Preet Sangha
+1  A: 

One the main practical issues which differ between the two is, when debugging it can be useful to have the individual steps on different lines with results being passed to local variables.

This means that you can cleanly step through the different bits of code which give the final result and see the intervening values.

When you build optimized the compiler will remove the steps and make the code efficient.

Tony

Tony Lambert
A: 

With your example there is an actual difference, as you in the first piece of code are creating objects and values that you don't use.

The proper way to write that code is like this:

object anObject;
anObject = this.FindName("rec" + keyPlayed.ToString());
Rectangle aRectangle;
aRectangle = (Rectangle)anObject;

Now, the difference between that and the single line version is that you are declaring one more local variable. In most cases the compiler can optimize that so that the generated code is identical anyway, and even if it actually uses one more local variable in the generated code, that is still negligable compared to anything else you do in that code.

For this example I think that the single line version is clearer, but with more complicated code it can of course be clearer to split it into several stages. Local variables are very cheap, so you should not hesitate to use some if the code gets clearer.

Guffa