Re: C# coding guidelines: use "this." or not when referring to member fields/properties within the object?



Michael C <nospam@xxxxxxxxxx> wrote:
"Jon Skeet [C# MVP]" <skeet@xxxxxxxxx> wrote in message
There are *some* things I take account of, but not very many. I use
StringBuilder when I don't know how many things I'll be appending,
because I know the results of not doing so can be catastrophic to
performance, for example. I don't try to put things in big methods to
avoid making method calls though - indeed, I positively split big
methods up into smaller ones, even if those smaller ones won't be
called by anything else. That hurts performance a tiny amount (if the
methods are still too big to be inlined) but improves readability.

I would never write a big function for performance reasons :-)

Goodo.

I certainly don't do that. I put them in the most logical way for the
reader to see them. Have you ever come across a situation (in C# - not
a different language which may have different characteristics) where
the order of the cases has made a significant difference? Have you
benchmarked it?

If there was a genuine reason to put them in a certain order, such as the
event handler for a menu then I would. But quite often there is no real
order.

In C# there pretty much always is - the order they're defined in the
enum, or the numeric order. Alphabetic for strings isn't quite so
useful, although it would still make it easier to find a particular
value when looking over the code.

What makes you think that reordering affects performance though? Have
you measured it (in C#, not VB6)?

I wouldn't accidentally do it, because I'd be doing step over instead
of step into. However, I've gone into why you *would* want to use
properties earlier in the thread. If you've provided some validation
etc in the property setter, not performing that validation should be
the exception rather than the rule.

The problem is you can't always step over. If the code is

DoSomething(MyProp);

then you can't step over MyProp and into DoSomething (afaik).

I *think* there's a way you can avoid it, but I can't remember it.

Besides I always forget to step over until I'm in.

If you think you won't want to step into those properties in general, I
believe there's an attribute you can apply to stop the debugger from
doing it. I'm blowed if I can find the name of it though :(

<quote>
I find that by writing the faster code to start with I save work
optimising later, which is going to be a significant saving over a few
rare changes
</quote>

I've been programming in vb6 for many years and it's much easier in vb6 to
write incredibly inefficient code. For example IIf(x=1, 5 , 10) is 50 times
slower (I tested this once) than using an if statement because the first
returns a variant and the second just deals in ints. Vb6 is full of such
traps and it's very easy to write page after page of inefficient code so
I've become much more aware of such issues. I didn't realise until I had
this conversation just how much more efficient C# is (in some ways at
least). I could easily think of 50 examples in vb6 but struggled to find one
for C#. And the one I came up with wasn't very good :-) I good example in
vb6 was I found out at one stage that "If len(SomeString) = 0" was much
faster than "If SomeString = "" " so I started using len. The 2 methods were
practically identical so why not use the faster.

Well, using the Length property is minisculy faster in C#/.NET too -
but personally I would still use if (x=="") because I find that easier
to read. Others find the .Length property easier to read, so they use
that - it's fine.

One example of where people go wrong is when they want to optimise loop
iteration. There are three obvious ways of iterating through a list or
an array - say of strings:

#1:
int len = list.Count;
for (int i=0; i < len; i++)
{
string x = list[i];
}

#2:
for (int i=0; i < list.Count; i++)
{
string x = list[i];
}

#3:
foreach (string x in list)
{
}

Now, people will use #1 because they think it makes it faster to only
look at the Count property once. In fact, #2 is faster than #1 (I
believe) because the JIT is able to make use of that common pattern and
optimise away the bounds checks - at least in some situations. (It may
be for arrays but not lists - I honestly can't remember at the minute,
and it may well change between CLR versions.)

However, #3 is the simplest and most readable form, if you don't need
the index itself. It says everything which is required and *only* those
things which are required.

Is it the most efficient? Nope. How often is that going to matter
though? The difference in performance is absolutely miniscule, so much
so that you'd only notice it at all if you had a virtually empty loop
and were iterating through millions and millions of times. At that
point, *if* you discover that's a bottleneck, that's the right time to
change to the most efficient form (assuming you can then prove that the
change does actually help). Until then, use the simplest form.

That suggests that speed is the major contributor to your design
decisions, rather than maintainability. If that's not your actual
position, then we may well have less to argue about - but I hope you
can see how statements like the one above have led me to my belief.
Perhaps I should have taken more notice of your "two methods which are
practically the same" to start with.

Don't worry, I don't go out of my way and make really bad designs to make
minor optimisations.

But do you go out of your way to make tiny changes to the code which
take it away from the path of clearest readability, just for the sake
of performance which is probably insignificant? How would you go about
iterating through a list in your normal code?

Not necessarily. The difference may often be that the beginner's app
will be very quick - but not actually work properly. I'd hope that an
experienced coder would concentrate on getting something working and
maintainable, only worrying about the speed of individual sections when
those sections proved to be significantly.

Generally the beginners code is slower and more buggy (and took them up to
10 times longer to write it). If you find performance issues with a more
experienced coder's work it usually harder to optimise it.

Well, it's likely to be harder to optimise the architecture, but you
may well be able to optimise the code itself, simply because plenty of
people take the same attitude I do.

The areas of speed I take into account are ones of complexity - I will
try to avoid doing something O(n^2) instead of O(n) unless I know that
n will be very small. However, that is usually a case of design and
architecture rather than actual implementation, IME.

That makes sense, the more loops a piece of code is inside the more critical
things become.

Sort of. I wouldn't be worried between a readable implementation and a
less readable one that was a constant 10% faster. When the *complexity*
is different, that's a real problem - and can get very ugly very
quickly, even if a loop isn't executed very many times.

For instance, suppose in one situation you have a loop which is
executed a million times, with a linear complexity. Changing the
implementation so that each iteration takes 10% less time will only
save 10% of the total time.

Now suppose you have a loop which is executed just 100 times, but it
becomes worse for each iteration so that the overall complexity is
O(n^3). Finding a way of making it O(n) will probably save *much* more
than 10% on the total time, even though the loop is only executed 100
times instead of a million.

--
Jon Skeet - <skeet@xxxxxxxxx>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
.



Relevant Pages

  • Re: Efficient looping
    ... > statement in the loop then run each loop and see which one goes faster: ... 22 microseconds per iteration ... strings, but I saw an improvement for longer strings, iirc. ... changed it to the foreach way. ...
    (comp.lang.tcl)
  • Re: memory management
    ... as they are declared outside the loop (actually twice the ... because all the intermediate strings are there from each iteration. ...
    (comp.lang.java.programmer)
  • RE: Error handling in a Do Loop
    ... I made the changes you suggested to my strings - blanking them correctly now. ... have any further suggestion or pointers, ... > When loop is able to ping a computer and able to pull the information, ... when the loop does not ping a computer/unable to ...
    (microsoft.public.windows.server.scripting)
  • Re: timeit module: am I missing something obvious?
    ... Why am I passing strings around when functions are ... best of 3 trials: 0.792 usec per loop ... quickly choosing number of iterations. ... - The result from the final pass through the convergence loop ...
    (comp.lang.python)
  • Re: Stupid Newbie Needs Help
    ... Without the loop the program works fine with the ... with 0-terminated strings, that way you can take advantage of C's ... hold up to 10 tokens, where each token may be up to 80 characters ... should give a clue of how the variable/constant/function/macro is ...
    (comp.lang.c)