Then under most usage scenarios the second one will be faster when A is usually an integer (assuming do_something needs an integer as input and will raise its exception fairly swiftly) as you lose the logical test from every execution loop, at the expense of a more costly exception, but far less frequently.

What I wanted to check was whether this is true in C#, or whether logical tests are fast enough compared to exceptions to make this a small corner case?

Oh and I'm only interested in release performance, not debug.

OK my example was too vague try this one:

Naive solution:

return float(A) % 20 # coerse A to a float so it'll only fail if we actually don't
# have anything that can be represented as a real number.

Logic based solution:

if isinstance(A, Number): # This is cheaper because we're not creating a new
return A % 20 # object unless we really have to.
else:
return float(A) %20

Exception based solution:

try: # Now we're doing any logical tests in the 99% of cases where A is a number
return A % 20
except TypeError:
return float(A) % 20

Examples using FSOs, database connections, or stuff over a network are better but a bit long-winded for a question.

5 Answers
5

Several .NET functions offer both variants for this reason. (int.TryParse, which returns a success code is often recommended because it is faster than int.Parse which throws an exception on failure)

But the only answer that matters is what your own profiling data tells you.
If you need performance, then you need to measure, measure, measure.

Because what was fastest on my computer, with my code, with my version of the .NET framework, at this time may not be the fastest on your computer, with your code, with your version of the .NET framework at the time when you read it.

@Abdul: please read the last paragraph of my answer. Test it for yourself. But note that I said "relatively", because compared to a simple branch on a boolean value, exceptions are very expensive. But compared to most of what goes on in an application's lifetime, exceptions are typically not a problem.
–
jalfJun 10 '11 at 11:26

As a rule of thumb, I would say that exceptions should not be used for flow control. Use exceptions for exceptional circumstances - so if you do expect A to be an int, then your first approach is sensible. If it could be an int or a string, the second is more readable.

Performance-wise there is a difference in a release build - sensible logical tests are certainly fast enough - so personally I would go for readability.

He specifically asked about performance, so talking about readability, no matter how true, is kind of missing the point.
–
jalfJun 10 '11 at 11:28

1

@jalf: As I read the question it is 'How should I approach this problem in the C# way, based on the approaches I know from my Python background?' coupled with 'Which would provide better performance in a release build', so I'd have to disagree with that comment.
–
mdmJun 10 '11 at 11:34

Sure. If you ignore the [performance] tag, the phrase "I'm only interested in release performance", and that he states that the exception version is faster in Python, and then asks "whether this is true in C#". Sure. Then performance is completely irrelevant
–
jalfJun 10 '11 at 11:38

2

What about the rules-of-thumb tag? I was simply trying to provide a balanced answer. Clearly I'm not going to win you over, so we'll just have to agree to disagree.
–
mdmJun 10 '11 at 11:48

3

The questioner is new to C# and is seeking advice from an experienced, knowledgeable C# user. If I were the questioner, or the random google searcher, it would be important that I have full knowledge of the incidental consequences of my choice. When answering a question, it's common to note any caveats that the questioner was not aware of, but needs to know. Namely: using exceptions for flow control is frowned upon in C#.
–
dss539Jun 10 '11 at 13:38

Exceptions should no be used as a "normal" execution flow control tool, and yes they are expensive.

Anyhow I think your question is slightly misguided, coming from python. C# is (or was?) a statically typed language which means that many scenarios similar to what you are proposing can be resolved at compile time.

For the case of some large number of iterations where the key exists (so the exception is never thrown) it's about 25% faster, but still fairly fast. Where the key never exists it's about 1000% slower.

Now bearing in mind that type checking is faster than looking up a key, and that .Net exceptions are, as mentioned above, fairly heavyweight, you'd need A to be an integer the vast majority of the time before it's even potentially worthwhile.