exception handling or pretesting?

D

Duane Evenson

I am grabbing chunks of a ByteBuffer for processing. The last requested
chunk's size will have to be shrunk to the amount remaining in the buffer.

Should I use a test to reduce the size, or should I use the try-catch
mechanism and handle the exception?

The two choices look something like this:
// pretest
while ( data.hasRemaining() ) {
if (size > data.remaining() )
size = data.remaining();
data.get(ba, 0, size) );
// process ba
}

// exception handling
while ( data.hasRemaining() ) {
try {
data.get(ba, 0, size);
}
catch (BufferUnderflowException) {
data.get(ba, 0, data.limit - data.position);
}
// process ba
}

Which is better code?
 
D

Daniel Pitts

Duane said:
I am grabbing chunks of a ByteBuffer for processing. The last requested
chunk's size will have to be shrunk to the amount remaining in the buffer.

Should I use a test to reduce the size, or should I use the try-catch
mechanism and handle the exception?

The two choices look something like this:
// pretest
while ( data.hasRemaining() ) {
if (size > data.remaining() )
size = data.remaining();
data.get(ba, 0, size) );
// process ba
}

// exception handling
while ( data.hasRemaining() ) {
try {
data.get(ba, 0, size);
}
catch (BufferUnderflowException) {
data.get(ba, 0, data.limit - data.position);
}
// process ba
}

Which is better code?
If the calling code can ensure a precondition, then it should do so.
Exceptions are for situations you can't easily or reliably predict and
prevent.
 
T

Tom Anderson

I am grabbing chunks of a ByteBuffer for processing. The last requested
chunk's size will have to be shrunk to the amount remaining in the buffer.

Should I use a test to reduce the size, or should I use the try-catch
mechanism and handle the exception?

In terms of general style, i'd go for pre-testing. Exceptions tend to
indicate to the reader that some kind of error or other bad, abnormal
situation is occurring. Hitting the end of the buffer is not the usual
case of a pass through the loop, but i wouldn't call it abnormal. Also, it
interferes with mental flow when reading: with the pre-test, when i get
the data.get line, i understand what it's doing. With the exception, i
don't fully grok the situation until i see and think about the catch
block, and then i have to revise my impression of what the get line is
doing - it's not just getting, it's probing for end-of-buffer.

Another issue here:
The two choices look something like this:
// pretest
while ( data.hasRemaining() ) {
if (size > data.remaining() )
size = data.remaining();
data.get(ba, 0, size) );
// process ba
}

// exception handling
while ( data.hasRemaining() ) {
try {
data.get(ba, 0, size);
}
catch (BufferUnderflowException) {
data.get(ba, 0, data.limit - data.position);
}
// process ba
}

Is that using exceptions means duplicating the data.get call. If you ever
needed to do anything else along with the get, this would become a pain.

tom
 
T

Tom Anderson

This is in accord with the literature on Java best practices, such as
Joshua Bloch's /Effective Java/. While premature optimization is a root
of evil, avoiding try-catch is a freebie when you can pretest. You get
cleaner code, 'assert'able conditions, none of the try-catch setup
overhead,

Which is what, exactly?

My understand, which is admittedly based on very old VM implementations,
is that in java, entering a try block is free (unlike in C++, at least on
the x86 and when standard ABI rules are followed). The catch has a cost,
but it's not paid until there's actually an exception.

I'm certainly not saying an exception is appropriate here, and i'm not
saying an exception would be faster, either - it might, but, especially
for shorter loops, it probably isn't - but i believe you may have a
mistaken understanding of the runtime costs of exception handling. Either
you do or i do, and either way, we should find out!

tom
 
T

Tom Anderson

Tom said:
My understand, which is admittedly based on very old VM
implementations, is that in java [sic], entering a try block is free
(unlike in C++, at least on the x86 and when standard ABI rules are
followed). The catch has a cost, but it's not paid until there's
actually an exception.

There's at least a little setup overhead, which I always thought was
negligible, but I've been warned by colleagues that old VMs have some
overhead in just setting up a try-catch. I have not confirmed that, but
it's not the main purpose to use pretests anyway, so who cares?

Fair enough. I'm just interested in establishing the truth.

In other exception news, i just discovered that you can 'deal with'
exceptions without a catch block:

public class AbuseFinally {
public static void main(String[] args) {
foo() ;
}
public static void foo() {
try {
throw new RuntimeException() ;
}
finally {
return ;
}
}
}

The exception is silently murdered and the body disposed of. It makes
perfect sense, but it had never occurred to me before. You can also do
this with a break or continue out of a loop enclosing the try-finally.

tom
 
T

Tom Anderson

It makes perfect sense to let an exception sneak through and crash your
program at a later, bizarre point dependent on the successful outcome of
the previous operation, with no logging at that earlier point to help
you debug the problem.

That answer, on the other hand, makes less than perfect sense. Are you
saying that handling an exception in this way is a bad idea? If so, i
agree - the point i was trying to make is that it's possible to evade
exceptions in this way, not that a was a good idea. It clearly isn't! Or
are you making some other point?

And what do you mean by "sneak through and crash your program"? The
exception here isn't sneaking anywhere - it gets stopped in the finally
block. Do you mean "vanish silently, leaving a failed operation unreported
and unhandled, thus causing your program to crash [at a later, bizarre
point]"?

If i was specifying a language, i'd be tempted to decree that a return in
a finally block is treated like a normal exit (ie execution hitting the
end of the block - return would become a 'goto end of block'), and that if
the block is being executed during an exception's flight, that continues
after a return. Thus, exceptions would not magically vanish.

tom
 

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,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top