开发者

To ask permission or apologize?

I come from a python background, where it's often said that it's easier to apologize than to ask permission. Specifically given the two snippets:

if type(A) == int:
  do_something(A)
else:
  do_something(int(A))

try:
  do_something(A)
except TypeError:
  do_something(int(A))

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 开发者_如何学JAVAone:

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.


Probably not. .NET exceptions are relatively expensive.

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.


Exceptions in .NET are fairly heavyweight, so the philosophy in C# is to use exceptions only for exceptional situations, not for program flow.

The philosophy in C# is also geared towards checking all input received from external code before using it. Example:

public void Foo(int i)
{
    if (i == 0)           // validate input received from external code
    {
        throw new ArgumentOutOfRangeException("i");
    }

    DoSomething(i);
}

public void Foo()
{
    DoSomething(1);
}

internal void DoSomething(int i)
{
    Debug.Assert(i != 0); // validate that i is not zero in DEBUG build
                          // assume that i is not zero in RELEASE build

    Console.WriteLine(42 / i);
}


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.


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.


http://paltman.com/2008/01/18/try-except-performance-in-python-a-simple-test/ has a similar test, except looking at has_key, which I'd expect to be (slightly) more expensive than type checking.

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.

But, as jalf mentioned earlier. Try it out and see.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜