try/catch

D

dmcreyno

I hate to bring this up again, but someone is trying to get me to do
something I wouldn't normally do.

I am being told keep all try blocks to a bare minimum in size. This is
leading to methods that have lots of small try/catch constructs
sprinkled about. IMHO, it makes the code bulky and less readable than
having a try/catch with a handful of catch clauses. While I have
abstained from following this advice so far, others are creating ugly
methods that we all end up having to maintain.

No one seems to be able to articulate exactly what problem is being
solved, just some vague references to performance which I find counter
intuitive. If a try clause causes the compiler to create a "protected"
section of code then more "trys" will lead to more "protected" sections
(protected: stack trace maintenance) and that souldn't be a good thing.
 
J

jan V

No one seems to be able to articulate exactly what problem is being
solved, just some vague references to performance which I find counter
intuitive. If a try clause causes the compiler to create a "protected"
section of code then more "trys" will lead to more "protected" sections
(protected: stack trace maintenance) and that souldn't be a good thing.

My understanding of try-catch performance penalties is that the generated
code does not impose any runtime penalty if the try block completes normally
(there is no JVM code or "awareness" of entering a block, even a try block).
Only if an exception is thrown does the JVM have to do a bit of extra work
(with the emphasis on "a bit of").

I'm afraid you're not alone by being told how to do things by people who
can't substantiate their reasons for doing it this or that way. When that
happens to me, I keep an internal counter of the number of such instances.
When the counter reaches an arbitrary psychological limit, I walk out of the
door and leave such teams to fend for themselves.
 
T

Thomas Hawtin

dmcreyno said:
I am being told keep all try blocks to a bare minimum in size. This is

You could put the body of the try statement in a different method. Then
the try block would be really small. To me this tends to suggest that
some symptom (possibly imagined) is trying to be fixed rather than the
cause. Perhaps the code mixes responsibilities, and that if separated
them out then a particular exception would be limited to only the
relevant code.
intuitive. If a try clause causes the compiler to create a "protected"
section of code then more "trys" will lead to more "protected" sections
(protected: stack trace maintenance) and that souldn't be a good thing.

Java exceptions are generally implemented very differently from C++.
Because there are no automatic object to destruct, the number of
(implicit) catch blocks is small (mostly from synchronized). When an
exception is thrown the JVM looks through where the program counter was
for each stack frame. In C++ by contrast, generally, code is produced to
maintain a linked list of destructors. This cost is incurred whether or
not the exception is thrown.

So the cost or try blocks in Java is non-zero, but very small.

Tom Hawtin
 
R

Robert Klemme

dmcreyno said:
I hate to bring this up again, but someone is trying to get me to do
something I wouldn't normally do.

I am being told keep all try blocks to a bare minimum in size. This is
leading to methods that have lots of small try/catch constructs
sprinkled about. IMHO, it makes the code bulky and less readable than
having a try/catch with a handful of catch clauses. While I have
abstained from following this advice so far, others are creating ugly
methods that we all end up having to maintain.

No one seems to be able to articulate exactly what problem is being
solved, just some vague references to performance which I find counter
intuitive. If a try clause causes the compiler to create a "protected"
section of code then more "trys" will lead to more "protected"
sections (protected: stack trace maintenance) and that souldn't be a
good thing.

Completely agree. The only other thing that comes to mind is that you can
do error handling with finer granularity. However to me this would
indicate that some refactoring was in order.

Kind regards

robert
 
C

Chris Smith

dmcreyno said:
No one seems to be able to articulate exactly what problem is being
solved, just some vague references to performance which I find counter
intuitive. If a try clause causes the compiler to create a "protected"
section of code then more "trys" will lead to more "protected" sections
(protected: stack trace maintenance) and that souldn't be a good thing.

Regarding performance:

It is possible that performance would be improved by using smaller try
blocks, but it's far from a sure bet. The reason performance might be
improved is that the control flow diagram is simpler, which means that
the JIT may perform more optimizations more easily. For checked
exceptions, this is unlikely to make any difference... but for unchecked
exceptions (and NullPointerException in particular) it may be
significant.

On the other hand, as you mention, it's possible that the JIT is
choosing an implementation of try/catch that requires work when
entering/exiting a try block. That would hurt performance for the
small-try approach. It's possible, but not likely.

Other:

There is, though, a much more significant concern that tends to keep try
blocks small, and it has nothing to do with performance. A catch clause
is written to handle a specific logical error. For some common
exceptions, the same exception class may be thrown in several places,
each of which is logically a *different* error condition. I can't tell
you how many times I've debugged error cases in code, and found that a
catch block was assuming problem A, when really problem B occurred. In
most such cases, problem B wasn't even anticipated. The answer here is
to keep try blocks short and include only minimum code that can throw
the exception for the error condition you expect.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Robert Klemme

Chris said:
There is, though, a much more significant concern that tends to keep
try blocks small, and it has nothing to do with performance. A catch
clause is written to handle a specific logical error. For some common
exceptions, the same exception class may be thrown in several places,
each of which is logically a *different* error condition. I can't
tell you how many times I've debugged error cases in code, and found
that a catch block was assuming problem A, when really problem B
occurred. In most such cases, problem B wasn't even anticipated.
The answer here is to keep try blocks short and include only minimum
code that can throw the exception for the error condition you expect.

Inspite of this I'd still rather have rather few try-catch per method.
For one, most of the time you catch only checked exceptions. And the
whole idea of exception handling (apart from the stack unwinding etc.) is
to have centralized error management (as opposed to checking the return
status of every method). It depends on the application of course but IMHO
genereally fewer catch blocks are better. My 0.02 EUR...

robert
 
D

dmcreyno

Chris Smith wrote:
There is, though, a much more significant concern that tends to keep try
blocks small, and it has nothing to do with performance. A catch clause
is written to handle a specific logical error. For some common
exceptions, the same exception class may be thrown in several places,
each of which is logically a *different* error condition. I can't tell
you how many times I've debugged error cases in code, and found that a
catch block was assuming problem A, when really problem B occurred. In
most such cases, problem B wasn't even anticipated. The answer here is
to keep try blocks short and include only minimum code that can throw
the exception for the error condition you expect.

I see and agree with your point. That being said, unfortunately this is
pretty much all Struts action related and all the try/catches are doing
the same thing since the only checked exceptions at this level are
custom application specific and they only have one exception the
business tier is allowed to throw. However, I would definitely take
this advice to heart in the business and backend tiers where we might
encounter many different exceptions.
 
J

jan V

On the other hand, as you mention, it's possible that the JIT is
choosing an implementation of try/catch that requires work when
entering/exiting a try block.

Sorry to be picky about this, but can you give any evidence that any
production JVM does anything on entering or leaving a try block (within a
try-catch context, not a try-finally)?

Last time I poured over class file disassemblies, I noticed a distinct lack
of any logic whatsoever inserted by the compiler to deal with *entering* a
try block. To me this suggests that try blocks, of themselves, do not impose
any performance hit whatsoever. My understanding of this stems from looking
at classes many years ago.. maybe things have changed since then, in which
case I'd like to see some evidence of this.

If you can point me to any JVM instruction supporting your claim, that would
be enough. ;-)
 
J

Joan

jan V said:
My understanding of try-catch performance penalties is that the
generated
code does not impose any runtime penalty if the try block
completes normally
(there is no JVM code or "awareness" of entering a block, even
a try block).
Only if an exception is thrown does the JVM have to do a bit of
extra work
(with the emphasis on "a bit of").

I'm afraid you're not alone by being told how to do things by
people who
can't substantiate their reasons for doing it this or that way.
When that
happens to me, I keep an internal counter of the number of such
instances.
When the counter reaches an arbitrary psychological limit, I
walk out of the
door and leave such teams to fend for themselves.

Isn't this the kind of behaviour that gives programmers a bad
name?
If your spouse asks you to get a carton of milk on the way home
from
work do you insist s/he substantiate his/her reason? Or I suppose
you
don't say anything for 6 months and then walk out.
 
S

Sanjay

Well I just wanted to add another point here.

With whatever I have read, I think the real performance hit would be
(if at all it is substantial), could be when the exception is thrown.

I have seen lot of code where custom exeptions are thrown as a good
programming practice.
This could be a performance hit since VM has to gather the stack trace
information.

So we can do some optimization by not throwing a newly created
object,but by throwing a common static object. In this case there wont
be any stack trace produced.
But beware this could be a problem while debugging the exception.
 
J

jan V

Isn't this the kind of behaviour that gives programmers a bad name?

What? Expecting to work with professional colleagues? ;-)

The description of the behaviour outlined was greatly simplified... of
course there are plenty of times when I would first ask people to give me
some rational reason, or a technically valid explanation, but all too often
making such reasonable, polite requests is greeted with frowns.. , also very
often the reason given is technically flawed, and the person making the
flawed statement refuses to accept the technically correct view, so
eventually one stops being reasonable and stops asking for justification. I
would have thought that's only normal human behaviour.
If your spouse asks you to get a carton of milk on the way home from
work do you insist s/he substantiate his/her reason?

I think you're confuse software construction with keeping a man-woman
relationship happy. I don't see any analogy..
 
C

Chris Smith

jan V said:
Sorry to be picky about this, but can you give any evidence that any
production JVM does anything on entering or leaving a try block (within a
try-catch context, not a try-finally)?

No, I can't. Nevertheless, it is not prohibited by any specification,
and I'm not familiar with all existing computer architectures; I can't
therefore say whether it ever happens or not. I *DID* say that it's
unlikely, which you then chose to ignore. I can't explain that decision
of yours either.

That said, though...
Last time I poured over class file disassemblies, I noticed a distinct lack
of any logic whatsoever inserted by the compiler to deal with *entering* a
try block. To me this suggests that try blocks, of themselves, do not impose
any performance hit whatsoever. My understanding of this stems from looking
at classes many years ago.. maybe things have changed since then, in which
case I'd like to see some evidence of this.

If you can point me to any JVM instruction supporting your claim, that would
be enough. ;-)

You are looking in exactly the wrong place.

Java bytecode is the input into a JIT compiler which generates native
machine code. The class file format separate exception handling into a
separate exception table, residing outside of the bytecode stream. The
entire format, including the exception table, acts as an intermediate
language.

However, the JIT needs to somehow arrange for exception handling to work
in native machine code. How it does that is going to depend on the
processor architecture and stack frame setup used in native code on the
target machine. It may or may not involve emitting one or more machine
code instructions to enter a try block. You won't see any evidence of
this in bytecode, which is platform-independent.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Thomas Hawtin

jan said:
Last time I poured over class file disassemblies, I noticed a distinct lack
of any logic whatsoever inserted by the compiler to deal with *entering* a
try block. To me this suggests that try blocks, of themselves, do not impose
any performance hit whatsoever. My understanding of this stems from looking
at classes many years ago.. maybe things have changed since then, in which
case I'd like to see some evidence of this.

I'm sure I could come up with evidence that try/catch may significantly
hurt performance. I don't think it would get us anywhere though.

The contents of class files do not necessarily imply the method of
execution. So evidence of what they contain is not evidence of how the
code is actually run.

Tom Hawtin
 
J

Joan

jan V said:
What? Expecting to work with professional colleagues? ;-)

The description of the behaviour outlined was greatly
simplified... of
course there are plenty of times when I would first ask people
to give me
some rational reason, or a technically valid explanation, but
all too often
making such reasonable, polite requests is greeted with
frowns.. , also very
often the reason given is technically flawed, and the person
making the
flawed statement refuses to accept the technically correct
view, so
eventually one stops being reasonable and stops asking for
justification. I
would have thought that's only normal human behaviour.


I think you're confuse software construction with keeping a
man-woman
relationship happy. I don't see any analogy..

It is the employee/employer relationship I was talking about.
 
B

Bent C Dalager

Well I just wanted to add another point here.

With whatever I have read, I think the real performance hit would be
(if at all it is substantial), could be when the exception is thrown.

Not when it is thrown so much as when it is created, since . . .
( . . . )
This could be a performance hit since VM has to gather the stack trace
information.

.. . . it needs to create a stack trace at that time. Actual throwing
and catching is comparably cheap.

Or so I've read somewhere anyway <g>

(Which is, I realise, what you probably meant to say in the first
place.)

However, if this is correct and if the computation is sufficiently
expensive that it might conceivably be measurable, there really ought
to be a way to turn off stack traces in exceptions. Most of the time,
you don't actually need the stack anyway.

Cheers
Bent D
 
W

Wibble

Thomas said:
I'm sure I could come up with evidence that try/catch may significantly
hurt performance. I don't think it would get us anywhere though.

The contents of class files do not necessarily imply the method of
execution. So evidence of what they contain is not evidence of how the
code is actually run.

Tom Hawtin
The basic rule you should follow in this situation is:

While whatYourDoingHurtsTooMuch()
increaseHowMuchYouChargeForIt();
 
R

Roedy Green

No one seems to be able to articulate exactly what problem is being
solved, just some vague references to performance which I find counter
intuitive. If a try clause causes the compiler to create a "protected"
section of code then more "trys" will lead to more "protected" sections
(protected: stack trace maintenance) and that souldn't be a good thing.

He may just be reacting to the other extreme a single try catch
(Exception e) for the entire application3.
 
J

jan V

Sorry to be picky about this, but can you give any evidence that any
However, the JIT needs to somehow arrange for exception handling to work
in native machine code. How it does that is going to depend on the
processor architecture and stack frame setup used in native code on the
target machine. It may or may not involve emitting one or more machine
code instructions to enter a try block. You won't see any evidence of
this in bytecode, which is platform-independent.

You've got a good point. I admit I wasn't thinking beyond vanilla JVM.. I
hadn't thought of any JIT implications. But still, having done lots of
assembler "in the old days", I still don't see why entering a try block
would require any special machine code sequence. The way I see it is that
it's the the throw event which triggers the logic which is going to cost you
cycles. It's the implementation of the throw which will need to scan the
exception tables etc.. and I still don't see how generating any special
"here we're entering a try block code" code would make all the difference to
the JIT performance of dealing with exceptions.
 
C

Chris Uppal

Chris said:
You are looking in exactly the wrong place.

Java bytecode is the input into a JIT compiler which generates native
machine code. The class file format separate exception handling into a
separate exception table, residing outside of the bytecode stream. The
entire format, including the exception table, acts as an intermediate
language.

There's a point here. The hardest part (IMO) of implementing
zero-cost exception handlers (the "zero" referring to the cost of
entering/leaving a protected block) is generating the maps from IP indexes to
handlers. The classfile format cleverly (this is one of the relatively few
things I genuinely admire in the classfile format) requires that the compiler
generate those maps, since that's the only way to express which code is
protected by which block. (The spec could instead have bytecodes for
entering/leaving protected zones -- as is the case with entering/leaving
monitors -- but happily does not.)

That means that for most reasonable JVM implementations -- whether naive
interpreters or clever JITing systems -- there is very little reason not to
provide actual zero-cost handlers. (Obviously a JIT will have to do more work
to maintain the mappings than an interpreter, but they are much more
complicated anyway, and I doubt if the /relative/ cost is significantly
greater).

In fact the only half-way reasonable implementation technique that would not be
able to take advantage of the maps is an implementation based on translating
the bytecodes into another high-level language that itself does not have
zero-cost exception handling. Personally, I don't know of any realistic
implementation that works that way, and I certainly doubt if any exist that are
intended for production use.

I suppose another circumstance where it might be difficult or impossible to
implement zero-cost handlers would be a machine architecture that was so
circumscribed that not even the lowest-level of machine-dependent programming
would give you access to the runtime stack. Maybe such architectures exist,
but -- again -- I don't personally know of any.

-- chris
 
J

jan V

If your spouse asks you to get a carton of milk on the way
It is the employee/employer relationship I was talking about.

You were talking about spouses and cartons of milk. Re-read your own post!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top