• Post Reply Bookmark Topic Watch Topic
  • New Topic

Loops and try...catch

 
Peter Chase
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a loop in which an operation is performed that may throw an exception. If it does, the loop needs to terminate, by throwing a different exception.
The original coder wrote it like this: -

Is there any benefit to recoding it like this:
 
Charles Lyons
Author
Ranch Hand
Posts: 836
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Personally I can't imagine that there is that much difference. However, having dealt with some very basic algorithms (mainly for sorting arrays), I would add this:
Every statement that is executed takes processor time, whether the statement be a variable assignment, iteration of a loop, or a simple test (e.g. conditional). I don't know how the exception mechanism works within the bytecode-level format of Java, but it may be that having to compute whether an exception is thrown on every iteration (your former example) uses more resource time that enclosing the whole loop within a single try-catch block. This depends upon how Java works with try-catch blocks: whether it converts them to native-style if(exception is thrown) goto line x; sort of test when a try-catch block is present, or if it uses some other advanced mechanism.
As a matter of typographical preference, I prefer the latter, as it seems tidier; every iteration of the loop may throw the exception, so why type it inside where it won't change? It would make more sense to enclose 'bits' of code within a try-catch inside the loop if only some of the code within the loop needs to be checked for exceptions.
Any comments on the byte-level format, or underlying native implementation of exception handling is welcome (unless this is the wrong forum for that topic!)...
 
David Weitzman
Ranch Hand
Posts: 1365
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Exceptions in Java generally only add overhead if you actually use them. I suppose a virtual machine could theoretically notice where checked exceptions may occur and somehow prepare specially for them, but since unchecked exceptions can be throw by any method the VM needs to be prepared for pretty much anything.
Basically it really doesn't make much of a difference which version you use. The overhead comes from throwing an exception, not from the mere existance of exception-handling code.
I think for the most part, a VM can just note where an exception occured, find the exception handling block in the exception table, and goto it. Or if we're talking JIT, I assume a "throw" with a catch block translates pretty directly into a goto.
In terms of raw bytecode, the two versions are basically identical. Here's the decompiled source of the two loops:

Basically they both have (if I counted correctly) 15 operations that accomplish the same end. The only difference is the exception table which I believe is basically a sort of generalized goto. The overhead of an exception comes from having an exception thrown in the first place, not from having code to handle that exception.
[ June 09, 2003: Message edited by: David Weitzman ]
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 35744
412
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The second one is faster. According to the websphere advisor article:
"You can achieve a simple performance improvement by placing the try-catch block outside any loops. On some JVMs, this can amount to as much as a 10 percent increase in performance."

Websphere advisor
 
David Weitzman
Ranch Hand
Posts: 1365
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the key in that article may be "On some JVMs". Perhaps on the IBM JVM it makes a noticable difference, but I wrote a short microbenchmark that seems to indicate otherwise for Sun's JDK 1.4.1. Here's what it looks like (I just chose two random checked exceptions. The commented out parts are there because I tried changing the order of the tests to see if it made any difference. It didn't seem to make any noticable difference):

Here are the results from the last three times I ran the benchmark on my crappy old laptop:
Inside: 7900
Outside: 7910
Inside: 7960
Outside: 7970
Inside: 7960
Outside: 7960
Inside: 7970
Outside: 7960
Inside: 7910
Outside: 8070
Inside: 7970
Outside: 7960
Looks basically the same, at least at 200 million iterations. I don't have an IBM virtual machine to test it on, though.
[ June 09, 2003: Message edited by: David Weitzman ]
 
Loren Rosen
Ranch Hand
Posts: 156
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's at least conceivable that some optimizers and/or JITs might do a better job with the try block outside the loop.
 
Kirk Pepperdine
Author
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have run several MBM's for each of the five tips and have so far, not been able to find then to hold. I had a small interaction with the authors of the paper but, it did not lead to any satisfactory explination as to why I was unable to reproduce the results.
I believe that our bartender got it right and that, the byte code tells all!
 
David Weitzman
Ranch Hand
Posts: 1365
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You shouldn't trust me because I was merely guessing and providing useless data to distract you . I'd never dealt with exceptions at the bytecode level and I thought it was kind of neat. I assume the JIT compiler is able identify which instructions are potential sources of exceptions so it doesn't end up sticking 'goto's after i++ just in case it throws a runtime exception.
But Kirk's findings are worth trusting . (he's part of the staff over at javaperformancetuning.com, in case you didn't know).
 
Dana Hanna
Ranch Hand
Posts: 227
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would say that regardless of performance, it's clearer outside of the loop.
Looking at the first snippet of code very quickly it appeared to me that the loop would continue after an exception (hence why the programmer put it in there). If you want to break the loop completely and not continue if any iteration throws an exception, you are better off putting the try catch around the loop for clarity.
However, one downside with this is that you have lost your index to the error causing index. If it would be useful for your error to know hat iteration it failed at you'd have to declare it before the loop, and leave off the declaritive part of the loop (or re-work into a do-while or while(true) with a break...).
Whatever, I'm blabbering.
 
Jamie Robertson
Ranch Hand
Posts: 1879
MySQL Database Suse
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Exception handling is not about performance. It's about dealing with problems during execution. The different placement of try/catch block should reflect your strategy for error handling only, not performance. You should place the try/catch block at the level that you want to deal with the exception.
The above code deals with Exception within the loop. The loop will not break when it encounters an error. Every iteration is tried.
Where as

breaks out of the loop when an exception is encountered.
The difference between the two isn't about performance, but about error handling strategy.
Just my $.02
Jamie
 
Peter Chase
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At risk of sounding rude, I don't think that you looked carefully enough at my original example. The handler for the exception throw another exception, so the loop terminated early. I believe that this means that my two examples were functionally identical.
My question about performance, therefore, stands, although it seems from other responses that there is little, if any, difference.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From a performance-only perspective, the difference is frequently negligible, but in some cases noticeable - the inner try/catch does indeed seem to interfere with some optimizations, even though it probably shouldn't. I saw a talk at JavaOne on "Performace Myths exposed" where the guy had actually tested various bits of code on about 7 different JVMs, and some of them did indeed show a differenct between an inner and outer try/catch. The session was TS-1522 - soon the slides from this should be available online, and I'll post a link when they are.
That said though, I agree with the gist of the other comments - it'ts rare that this will matter much, and other concerns like readability are usually more important. And Dana correctly identified the best reason I can see why you might use the inner try/catch despite its inferior readiability (and possibly inferior performance) - the index might be useful information to include with the exception. (Even if you didn't include it in your example.)
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi all
as Dana pointed out...
i have observed the requirement of having try...catch in a loop instead of outside in using Mailing application.
if i have a list of emails and i'm not sure if some of them really r true or not (though the email syntax is correct) then v don't want to exit the program w/o sending email to others after we encounter a wrong email address, right? (well depends on the application)...so in this case we would need to put try...catch "in" the loop instead of outside.
there is an optional method to above problem as we can "pre-check" if all the addresses are correct by a method before trying to send an email but that might be overhead if anyways putting try..catch inside the loop doesn't gain much benefit to us than putting it outside the loop..

regards
maulin
 
Jamie Robertson
Ranch Hand
Posts: 1879
MySQL Database Suse
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Peter Chase:
...I believe that this means that my two examples were functionally identical...
Peter, I was just trying to illustrate the only reason you would have a try/catch block within the loop, and that is so that you can keep looping, it had no reference to your original examples.
I just can't understand WHY you would want catch an exception, only to rethrow it without any other type of error processing.
but we only know a sliver of the complete picture so there may be a lot more to it than you posted,
Jamie
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just can't understand WHY you would want catch an exception, only to rethrow it without any other type of error processing.
You may be implementing an interface (or overriding a method declaration) which does not allow the original exception to be thrown, so you are converting the original exception to an acceptable type (e.g. RuntimeException). This may or may not be a good idea from a design perspective - it often indicates the original method declaration was flawed. But sometimes you've just got to work with that declaration anyway...
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
I just can't understand WHY you would want catch an exception, only to rethrow it without any other type of error processing.
You may be implementing an interface (or overriding a method declaration) which does not allow the original exception to be thrown, so you are converting the original exception to an acceptable type (e.g. RuntimeException). This may or may not be a good idea from a design perspective - it often indicates the original method declaration was flawed. But sometimes you've just got to work with that declaration anyway...

Or you may want to handle the exception somewhere else without having the intermediate code to know about it. In fact the more I get a feeling for (what I think of as) good OO design, the more I seem to also feel the pain of checked exceptions...
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!