My First PDC05 Talk

I gave my first talk of two today.  If you went there today and you’re reading this perhaps you’ll consider joining me tomorrow for the memory issues talk.  It’s more technical than this one was but I’ll still try to make it fun.  On the other hand perhaps you’ll want to flee to avoid the boredom of it all… I hope not :)

I’d like to invite any of you to ask questions regarding the talk, or pretty much whatever in the comments here.  I’ve got lots more time than usual to answer questions this week so feel free to chime in.  I expect that the talk will be posted soon — when it is I’ll be sure to let you know.

One thing I wanted to talk to is a question I’ve got from several people regarding try and catch and throw costs.  I said that the CLR optmized for cheap “try” at the expense of throw, although maybe I didn’t say it quite so clearly as that.  What I meant was this:  the general design philosophy of the CLR with regard to exceptions is that we want to make entering a try block free even if that means that when a throw happens we have some extra cost.  It’s a design choice — there are other strategies which would cheapen the throw at the expense of running code on the try.  We’ve opted for the free try.  That’s good news for those of your writing try and try/finally blocks because there is no cost when an exception doesn’t happen (the norm).

For those of you who saw the talk, I hope you enjoyed it and please fill out and eval.  Hope to see you tomorrow same place and time.  Even though FUNL05 isn’t on the short calendar, due to space limitations I guess, I’ll be there!

Comments (4)

  1. joc's bLog says:

    Another fun day at the office today, with a host of different customer issues and questions to work on….

  2. barrkel says:

    Unfortunately, the cost of a thrown exception on a server means that good C# server design should avoid exceptions, even for business errors that need messages propagated to the client.

    This seems to force a move back to return values. Business developer code becomes littered with return value checks, and speed suffers because lots and lots of extra if-statements. Properties must be abandoned because they can’t have a separate return value. No expression can contain more than one method call.

    The productivity cost of checking return values, abandoning properties, and breaking down even simple expressions is too much. So, at my company, we use exceptions for business errors, and accept the performance hit. We hope that MS will see the light in the future and reduce the cost of thrown exceptions, even at the expense of a little cost for a try block.

  3. Rico, excellent talk. I look forward to the next one, and I plan on coming to talk with you this evening at Ask-the-Experts.

    In response to barrkel,

    Not to criticise your business approach, but I did have some feedback that may be pertinent to your problem. I understand the goal of the pattern you are using: signalling rich business error information to the user. However, your particular approach has two problems.

    First, this kind of behavior really equates to program logic, not exception logic, and exceptions are not meant to control program flow.

    Second, exceptions are meant for developers, not for users.

    Although achieving your desired program behavior without using exceptions would be nontrivial (perhaps impossible at this point), I would make the assessment that you are leveraging an inappropriate mechanism, and therefore you are incurring extra cost.

    Ideally, the performance cost of throwing an exception should be irrelevant, since exceptions relate to "exceptional" circumstances. Microsoft is making better attempts to correct some of the mistakes they’ve made in v1.0/1.1 in this regard (e.g. Parse -> TryParse), and there are a lot of published resources that talk about best practices for exceptions.

    In particular, a method should typically not throw exceptions that the caller cannot avoid. For example, determining validity of the business rule should be a separate call that returns a boolean and/or other information, and activation of the rule should be a separate call.

    Ultimately, a business rule error is not an exceptional circumstance; determining that a business rule has an error it is not a failure in the code. Rather it is a successful determination that certain input data is not consistent.

    All evaluations are subjective, and there is never a "right" way. In fact, there are many framework patterns (and patterns in my own code) that go against this very principle. But this is just my opinion on the "ideal" usage…

  4. barrkel says:

    Steven: ‘Ideally, the performance cost of throwing an exception should be irrelevant, since exceptions relate to "exceptional" circumstances.’

    For exception throwing cost to be irrelevant assumes that a correctly executing program never throws an exception. This would imply that exceptions could be trivially be abandoned, and we could return to C++ style ASSERT macros that terminate the application with just a stack trace and error message.

    Clearly that isn’t the model for .NET applications. My understanding of the rest of your comments is colored by this.

    ‘Ultimately, a business rule error is not an exceptional circumstance; determining that a business rule has an error it is not a failure in the code. Rather it is a successful determination that certain input data is not consistent.’

    The problem with this statement is that the error might be anywhere in a possibly deep call tree, nested inside property getters and the like. It’s not like all business code is simple methods which validate input, with a boolean result. To propagate error information without exceptions, some other mechanism (most likely return value possibly combined with thread-static variables) must be used.

    My essential point is this: to clutter business developer code with COM-style HRESULT checking (which even extremely competent C++ developers don’t get right 100% first time), or some variant thereof, is too much of a productivity hit, and in fact is the antithesis of what .NET is all about. .NET shouldn’t have exception throwing performance that echos C++ anti-exception cults.

    Don’t forget, all the HRESULT / boolean result checking (or whatever replacement for exceptions that is chosen) also has a cost. The cost is in runtime performance, code bloat, code readibility, programmer productivity, code maintenance, and the training cost of non-standard error handling.

    The cost of making thrown exceptions slightly cheaper, and entering try-blocks slightly more expensive, is runtime performance.

    I just don’t see the business case for the position your standing at, Steven.