Does try-catch significanlt influences game speed?

I was wondering if the try-catch block significantly influences the game speed. Let’s say I have a map class that draws something each frame. If something goes wrong, it throws a MapException. Because of this, in my game’s rendering method I have something like this:

try
{
   Map.render();
}
catch (MapException mex)
{
   System.err.println("Error with drawing the map");
   System.exit(1);
}

Now this part of code is called probably about 50 times per second, so I was wondering if it’s severly influencing the game speed. Throwing and catching errors is not that important anyway cause once the game is built up a map won’t be able to throw any exceptions cause there will be none, but if it doesn’t influence the game speed I might leave it there just in case the user’s computer explodes ;D

Catching exceptions in pretty expensive. As a general rule, you wouldn’t want one in a rendering loop. For developing it won’t hurt though.

try costs effectively nothing, catch costs 100 x a normal method call (yes, 2 orders of magnitude).

So, use exceptions for exceptional situations, NEVER for control flow…

[quote]try costs effectively nothing, catch costs 100 x a normal method call
[/quote]
Do you think you could write something to demonstrate this figure without being classifed as a ‘microbenchmark’?

-Chris

It’s a Known Fact ™. It used to be more, IIRC, (although not sure).

“Known Facts” ™ are always the most suspect. :wink:

In fact, catch is not terribly expensive at all. What IS expensive is creating the stack trace when you create the exception.

A questionable but sometiems useful practic is to pre-generate the exception and save it.

If you do this then each throw is not very expensive at all.

The questionable part is that what youa re telling the code catchign the expcetion is nto the actual state at excpetion time but an analgous state you manufactured earlier. The last line or so of the trace will be wrong. How wrong and how much of it is wrong depends on how clsoe to the actual throwe statement you did the earlier “new”.

Biggest issue here though is this…

Yo ushould NEVER be using try/catch as aprt of your normal execution logic.

Exceptions are for EXCEPTIONAL conditions, thats why they are called exceptions. The system is going to assum that if you are throwing an exception you are outside of normal opration and thus its really free to take as long as it wants to.

DON’T use exceptions except where a genuine unexpected condition has ocurred. Thats what they are for.

[quote]“Known Facts” ™ are always the most suspect. :wink:
[/quote]
Yep, which is why I flagged it like that :stuck_out_tongue: so that people would know what baggage the statement came with. Just recently I saw some detailed figures for the catch penalty, compared across gcc/msvc/java in lots of different configurations, and it’s still clearly “a lot”.

You cannot go around using exceptions as part of your normal control flow if you care at all about performance. It’s not something that is WORTH the JVM vendor optimizing (it serves no purpose; people who need faster catch are abusing it), so … don’t even try to use it because likely it’ll never get much faster.

Of course. When I said “catch” I meant “the execution of code that is done to implement the catchng”, which necessarily includes capturing the stack trace, and seemed the most obvious interpretation given the context.

Throwing and catching exceptions within your constructors or deinitialisations methods is fine.

Outside of constructors/deinitialisations methods within your game, you should avoid throwing exceptions alltogether because like the people above have said it will drag down your performance.

This sums it up quickly. :slight_smile:

Nah, using exceptions outside of constructors is fine as long as you use them appropriately. It will not affect performance.

Except it doesnt. Read the end of that post.

In any event, its not part of a catch at all. It IS part of a typical throw but, as I said, thats avoidable if you really need to avoid it.

Precision of thought is important in performance tuning as it leads to precision of action.

Sigh. I understand perfectly what you’re saying, but you’re not realizing the intent I was explicit about conveying. Shrug. If you’re going to highlight the value of precision, I’m going to highlight the value of trying to understand people rather than just reading their words as gospel :P.

To say what I said before, in a different way: I meant “everything from the moment of moving out of the non-exception-related code and into the exception-related code up until the point you move back into non-exception-related code” but was glossing over the details for the reasons I described - it just doesn’t matter IMHO.

By taking my words too pedantically and not paying attention to the concept you mistook what I said :stuck_out_tongue: ;D

I don’t think you’re understanding what he’s saying at all.

for (int i=0; i<100; i++) { try { foo(); } catch (RuntimeException e) { bar(); } }

You seem to think that that code is slow because of the catch in there.

It isn’t.
In fact, it’s not much slower than this:

for (int i=0; i<100; i++) { foo(); }

Sure, it’s slower, but certainly not by orders of magnitude.

The thing that makes an exception slow is the creation of the exception, not the catching.

To make it really clear, this is horribly slow:

for (int i=0; i<100; i++) lastException = new NullPointerException("omg!");

[quote]I don’t think you’re understanding what he’s saying at all.
[/quote]
I think it is you who is misunderstanding now.

I think blah^3 is saying that the code needed to actually process an exception, is slow. This code by necessity includes creating an exception object. Even if you pre-create it, we are talking about the cost of creating the object, not when you do it.

Exception processing as it is discussed above includes creating the exception, the ‘throw’, all the stack unwinding, and the ‘catch’

You can optimize the really expensive part of that by pre-creating the exception objects as Jeff stated. That will have side-effects that are also stated in Jeff’s post. If exceptions are used properly (only in exceptional circumstances) I can’t think of a good case for doing that optimization.

In any case, as you point out, the safety net of the try-catch block itself is not a significant factor.

Oh, ok. So whenever someone says something blatantly wrong, I’m supposed to ignore it and assume he really means the right thing? Gotcha. =)

Yes. Thank you. Without putting too fine a point on it, I’m somewhat suprised by the narrowness of perspective here: that people can’t read “the code that does X” to mean “the compiled instructions” that “make X happen” rather than “the lines of source I write in a sequential block” that “do a very precise part of a bigger process, and don’t make sense on their own conceptually but are just one small aspect of the concept”.

When talking about performance, what I care about is what actually happens. When comparing inserted code, what I care about is what the difference in execution paths is, and what one does extra that the other does not do. I say this only to try and clarify my perspective here. Maybe it’s not the best way to look at things (? Suggestions gratefully received…) but to date it’s served me extremely well in writing high-performance code, typically outdoing the best that anyone else had come up with in the same areas.

In the midst of all this, I forgot to say this, but I think that’s a very neat trick. Suicidally hacky, and something to avoid like the plague, but still a neat trick ;D. I can see myself perhaps using it in the future, as one of my toolbox of “vile horrible things you very occasionally have to do in java when you’re writing very powerful code and run up against the barriers of java forcing you to do things because it errs on the side of caution even when you can statically determine such erring is useless”.

But you were wrong!

You said that catching an exception was slow. It isn’t. Throwing an exception isn’t slow either.
If people listened to what you said, they’d avoid doing things like catching an exception, processing, and rethrowing the same exception.

That’s virtually free compared to the cost of creating a new exception, but from your explanation (“a catch is orders of magnitude slower than a normal method call”), you’d think it was slow.

Bah, fine. I’ll start saying things like “you drink coffee with a fork”, then say that “of course everyone realizes that you have a CAKE with your coffee! What else would you use the fork for?”

Judging by you two arguing, can I conclude that it’s the creation of the exception which is the slowest part?

Basically, this is ok:


      try {
            render();
      } catch(HorribleSystemException e) {
            showGameUnableToContinueDueToSystemFaultDialog(e);
      }

and this is not:


      try {
            getPacmanMovement();
      } catch(PacManMoveRightException e) {
            moveRight();
      } catch(PacManMoveLeftException e) {
            moveLeft();
      } catch(PacManMoveUpException e) {
            moveUp();
      } catch(PacManMoveDownException e) {
            moveDown();
      }

Regards,

  • Vincent

[quote]Judging by you two arguing, can I conclude that it’s the creation of the exception which is the slowest part?
[/quote]
Yup.

And also using pre-cooked exceptions as control flow is much slower than any other reasonable solution (such as checking return values for a special error code). Under very restricted circumstances the server compiler will manage to make such control flow close in speed to the obvious test&branch, normally you should expect that throwing & catching a pre-cooked exception to be at least 10x slower than simply testing a return condition.

Declaring a try block and not throwing is free (nearly) so it doesn’t cost to be robust and catch exceptions that are rarely thrown.