Re: Avoiding Default Parameter Checking in C# 4.0

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Dec 3, 10:50 pm, Peter Duniho <no.peted.s...@xxxxxxxxxxxxxxxxxx>
wrote:
jehugalea...@xxxxxxxxx wrote:
The count method was just an example. To explain the ToIList method,
it acts a lot like the ToList method. If it is not an IList, it simply
creates one from the argument.

That doesn't change the point I made.  Specifically, there's no obvious
reason that a) a null input should be an error, and b) none of your
explanation of the ToIList() method suggests a need to factor it into
two pieces, one for argument checking and one for implementation details.

Blah.ToIList(list) should work the same as list.ToIList(). Agree or
disagree?


Also, it is better to enumerate the IEnumerator instead of using a
"foreach" because there is no need to inspect the values of the
collection.

The enumerator copies them somewhere, whether you look at them or not.
And the JITter can easily refer directly to that "somewhere" (i.e. the
IEnumerator.Current property) rather than actually copying the value
again to a new variable.

If you were working on a value type, such as DateTime or
Decimal, you would be copying a lot of data unnecessarily.

How do you know that?  Have you actually proven that in production code,
using IEnumerator directly to count items in an enumeration produces a
significant performance improvement over the simpler, more maintainable
approach?

It's just a minor performance enhancement.

I remain unconvinced that it's a noticeable performance enhancement at
all.  I'll bet that even in a trivial benchmark that only enumerates,
there'd be no practical difference between the two, and certainly in
code that does something interesting with the enumeration, any
difference that may exist (if any) would be inconsequential.

Try it. I bet it doesn't do much for performance either. However, why
bring a variable into existance if you're not going to use it.


You also have to wonder whether C# uses
a using block when looping over an non-generic IEnumerable. It is
guaranteed for IEnumerable<T>, but how could it know prior to runtime
whether to do resource management or not?

I don't know whether it does or not either.  I haven't bothered to look..
  The fact is, it would be trivial at run-time to do an "as IDisposable"
check and dispose if necessary.  In fact, I'm pretty sure this is what
happens if the foreach is on an IEnumerable instead of IEnumerable<T>.

I'd like to experiment with this one also. But why risk it?


On the other hand, the IEnumerator interface itself doesn't inherit
IDisposable, and so other code (i.e. not auto-generated by the language)
still has the same problem if someone winds up using the IEnumerable
version.

That's probably why there aren't many implementations out there that
utilize this feature. Personally, I think it just makes things more
complicated. It is like providing a solution to a problem that only 2%
of the community cares about. It might be cool if someone create a
StreamEnumerator that took a file name and returned each line as an
item. using in the situation could be nice to close the stream.
Perhaps something similar with a database query? However, I think a
more explicit approach would be better.


My guess is that it foregoes
using a using, and this is not the expected behavior (although I have
only seen one example where IEnumerator<T> actually needed to be
IDisposable).

It should be rare.  As far as foregoing "using" goes, that's a
non-issue.  The "using" statement is for people writing C#.  The C#
compiler isn't writing C#; it's just emitting MSIL.  So it can just put
the same try/finally pattern in place that it uses for "using", with the
small modification of checking for the IDisposable implementation before
trying to dispose.

Yes, of course. I am just unsure that the compiler would even bother
checking for IDisposable. I don't know the runtime impacts of dynamic
type checking, but I'm betting MS wouldn't do it for ever foreach
loop. It would just cost too much. Again, why risk it? Just write your
code under that assumption.

On a similar note, ADO.NET IDbCommand objects are supposedly
IDisposable as well. However, aside from myself, I don't know any
programmers who bother to surround a command with a using block. They
do it for the connection and IDataReaders, but not IDbCommands. It's
reasonable to ask, "What could there be needing disposed?" I can't
think of anything! Nonetheless, I use a using anyway. Just about the
only thing I don't use a using for are Forms.


The overhead of calling private methods isn't that significant.

No, I agree...it's not.  But neither is argument checking.

I agree. So why pay for a method call when you can avoid it? So why
pay for an argument check when you can avoid it? I suppose it matters
which one you are going to do more often. If you are calling a method
from outside the class, it's probably is faster to not have a private
method. If you are going to be calling a lot from within the class,
it's probably faster to call an unchecked implementation.


You're
probably right that this costs more than a couple argument checks
(except in the case of reflection). It is not always justifiable to
create a whole new method just to put your implementation details.

I'd say it's almost never justifiable to create a whole new method just
for implementation details.  The first method is (should be)
"implementation details" itself anyway.

See, I think there is a big difference between code that does
exception handling, resource management and argument checking and the
actual business logic. The core code should be oblivious to such
considerations and operate in a "care-free" manner. All that other
stuff is just necessary fluff as far as I am concerned. It helps other
programmers filter out what is and is not important. So what if it
requires an extra method call?


I rarely have classes that call their own methods.

I agree that it's not very common for a class to have to call its own
public methods.  But, that's not the point.  The point is whether it
makes sense to have a policy to specifically _avoid_ calling one's own
public methods.

Just because it doesn't happen very often, that's no reason that if it
does come up, one should try to avoid letting it happen.

My experience says otherwise.


However, when I do, I
usually extract the logic to avoid unnecessary argument checking, etc.

Yes, again...we understand that.  That's where we started this
discussion.  :)

I have found that if I am extremely vigilant, some methods can become
static, instead of instance methods.

Irrelevant to the question of refactoring to separate argument checking
from implementation.

If enough of these appear in the
class, and they are related, I usually create a "helper" class. It is
a great way to discover unexpected code reuse.


Sometimes the only way you find a better solution is to make
opportunities for them during development. In that sense, it is very
relevant. I have wound up with entire libraries that initial started
out as private static methods. I wouldn't have even noticed it had I
always written my logic in-line.

See above (i.e. irrelevant).

Another thing to remember is that the logic within a method can be as
simple as a if/else statement or extremely complex. The more time
consuming the method, the less and less significant a little method
call overhead becomes.

Likewise argument checking.  I.e. not a factor that argues in favor of
one approach or the other.

I'd say it is less in favor of my approach.


When calling between members, the call is going
to take place no matter what; it is just a matter of which methods
call which.

Likewise client code calling public members.  Again, not a factor in the
discussion.

Personally, I like to think of the internals of a class as a free-for-
all. Once inside, there are no restrictions. I trust that my class is
intelligent enough to know how to work on itself. Personally, I like
to think of ArgumentException and its derivitives as uncatchable
exceptions. It's not the user's fault or bad data; it bad programming.
Somehow I let something through that I shouldn't have. Perhaps I need
better UI validation or perhaps I just screwed up. In opposition to my
policy, immediately detecting bad arguments would make it easier to
resolve such bugs. However, all that extra code just clouds up the
significant logic. I say buy yourself the argument checking on the
public methods but give yourself the clarity of care-free private
methods. If your class is well-designed, it will be easy to work out
any obvious internal bugs with unit tests. At that point the argument
checks are really for later when you need to use your class in
collaboration with others.


In my experience, calling public methods from others has caused me
problems.

In my experience, bypassing argument checking in arbitrarily chosen
situations has caused problems.

It's not arbitrary at all. If you want to reduce the number of these
private, care-free methods floating around, make your classes smaller.
90% of the time it is just a public method calling its private method.
There isn't much calling of one private to another.


I lose track of which methods do what. I know this may sound
horrible, but my public interfaces change quite often during
development. Refactoring and all... Strangely, my private
implementations rarely change, just how and when they are called. This
seems a bit backward, but it's the truth. I mean, well factored logic
isn't going to change often; just how and when it is called.

That all makes sense for private implementation that isn't just a repeat
of the public API.  But obviously what you wrote does not apply to
private implementation methods that are simply called directly by a
method that has as its only purpose argument checking.

Here is an example. Suppose you write your class to originally support
a range between two numbers. Then 6 months down the road you decide to
support ranges that include a starting number and the number of
numbers (count). You can still use the same private implementation,
just by modifying the input arguments. If you had your logic inline
with your argument checks you could have achieved the same thing.
However, before when you had a start and stop, now you must calculate
the stop. So you have the "count" variable sitting around for the rest
of the method that doesn't do anything else.

pri


Nothing in our profession should always be done one way; there's
always a special case. For this policy, there are probably about a
hundred. I take a lot of care when breaking apart my code, so I'm not
100% sold on the idea either. Personally, though, it has really paid
off and seems to scale well.

Okay.  I remain unconvinced, but it's your code.  :)

Different experiences I suppose. For me it has always seemed to reduce
complexity and promoted small, cohesive classes. The larger the class,
the more likely there will be methods calling methods and argument
checking flies out the window. With a small class, you can clearly see
where the logic is and the flow of execution.


Pete

.



Relevant Pages

  • Re: OOP database tables <-> php interface (semi LONG)
    ... Does the factory design pattern in this case ... In the meantime I read a little further on the factory stuff, and indeed saw that you could make the constructor method private. ... What would seem important here also, is to have as little public methods and properties as possible. ...
    (comp.lang.php)
  • Re: Access modifier : private
    ... But my confusion is, even though i mark it as private, it is ... with a receiver. ... def initialize ... puts "m2 calling self.m" ...
    (comp.lang.ruby)
  • Re: Empty Type Library
    ... Your 'DoSomething' method is private (you haven't given it any explicit ... no public methods for the class at all it won't generate anything at all for ... the tlb file does not contain any type ... > public class MyClass ...
    (microsoft.public.dotnet.framework.interop)
  • Re: Canadian DJs Pull a Priceless Prank on Palin
    ... take as vp or heaven forbid President? ... Not just funny but scary that it would be so easy to fool her. ... No caller ID apparently which would presumably reveal they were calling from Quebec (unless they actually ... I assume it was a private line since why ...
    (rec.arts.tv)
  • Re: When to Use protected
    ... Murali Krishna wrote: ... im relative new to Java and im wondering: what are the rules of using ... private vs protected vs public methods. ... So, when a method is used only within the class itself, use private. ...
    (comp.lang.java.programmer)