Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2005

Tip: Looking for answers? Try searching our database.

Java Exceptions cause performance hit?

Thread view: 
kk_oop@yahoo.com - 13 Jul 2005 16:21 GMT
Hi.  I wanted to use exceptions to handle error conditions in my code.
I think doing that is useful, as it helps to separate "go" paths from
error paths.  However, a coding guideline has been presented that says
"Use conventional error-handling techniques rather than exception
handling for straightforward local error processing in which a program
is easily able to deal with its own errors."

By "conventional error-handling," I believe they mean returning an
error code, or just handling the error without going to a catch block.

When I said that I'd prefer throwing and catching exceptions--and that,
in fact, exceptions is the "conventional error-handling technique" in
Java, I was told that since we have a real-time system, we can't afford
the performance hit caused by using exceptions.

Do exception blocks cause big performance hits?  If so, what causes the
hit?  Or is the person just misinformed?

Thanks for any info,

Ken
Steve Wampler - 13 Jul 2005 16:55 GMT
On Wed, 13 Jul 2005 08:21:12 -0700, kk_oop wrote:

> Do exception blocks cause big performance hits?  If so, what causes the
> hit?  Or is the person just misinformed?

I don't know how Java implements exception handling, but having
done it in another language I would say that the only significant
performance hit *should* be the construction of the stack trace
(and even there one could argue about the definition of
'significant'...).  Plus, the ability of an thrown exception to
perform a 'deep return' may help mitigate that cost.

Personally, I think the benefit outweighs the cost, but I could
understand someone (especially in a RT system) possibly wanting
to cut that cost out - particularly if the stack trace could be
turned on/off dynamically).

One wonders, however, what Java version you're using in a
real-time system...
Eric Sosman - 13 Jul 2005 17:04 GMT
> Hi.  I wanted to use exceptions to handle error conditions in my code.
> I think doing that is useful, as it helps to separate "go" paths from
[quoted text clipped - 13 lines]
> Do exception blocks cause big performance hits?  If so, what causes the
> hit?  Or is the person just misinformed?

   Creating, throwing, catching, and eventually garbage-
collecting a Throwable object is certainly a lot more work
than a simple `if'.  You can measure it for yourself by
comparing the time required for two different ways of
filling an array:

    for (int i = 0;  i < array.length;  ++i)
       array[i] = i;

    try {
       for (int i = 0;  ;  ++i)
           array[i] = i;
    } catch (ArrayIndexOutOfBoundsException ex) {}

(This is pretty much the same experiment Joshua Bloch shows
in "Effective Java.")  On the machine I'm using at the moment,
the exception-based approach takes 15.5 times as long as the
straightforward loop to fill a 100-element array; that is, one
exception takes longer than 1500 limit tests.  Your machine
may give different timings; try it and see.

   Note that the guidance you've been given does not forbid
the use of exceptions; it only forbids them for "straightforward
local error processing."  I suggest you go back to the folks
who wrote the guidelines and ask what "straightforward" means;
it will probably turn out to be less burdensome than you seem
to fear.

Signature

Eric.Sosman@sun.com

Andrea Desole - 13 Jul 2005 17:22 GMT
>     Note that the guidance you've been given does not forbid
> the use of exceptions; it only forbids them for "straightforward
> local error processing."  I suggest you go back to the folks
> who wrote the guidelines and ask what "straightforward" means;
> it will probably turn out to be less burdensome than you seem
> to fear.

Good point.
I was just wondering why worry about performance if an exception is for,
well, exceptional cases. If an exception is being thrown so often to
have a performance impact, either you have a problem with your code or
you have a problem with your system.
Maybe that person just wants to prevent exception abuse
Cantankerous Old Git - 13 Jul 2005 18:45 GMT
>>     Note that the guidance you've been given does not forbid
>> the use of exceptions; it only forbids them for "straightforward
[quoted text clipped - 9 lines]
> you have a problem with your system.
> Maybe that person just wants to prevent exception abuse

I haven't done any testing, so I speak in ignorance, but could it
be that setting up the try/catch block is expensive? This will
have to happen whether an Exception is actually thrown or not,
and will therefore affect error-free performance too.

The Cog
Eric Sosman - 13 Jul 2005 19:13 GMT
>>>    Note that the guidance you've been given does not forbid
>>>the use of exceptions; it only forbids them for "straightforward
[quoted text clipped - 14 lines]
> have to happen whether an Exception is actually thrown or not,
> and will therefore affect error-free performance too.

   Look at the bytecode, and you'll see that it's very
cheap.  The cost amounts to one unconditional jump at the
end of the `try' clause to skip over the `catch' clause(s).
It's possible that the JIT compiler might reorganize the
compiled code to eliminate even that much overhead.

Signature

Eric.Sosman@sun.com

Andrea Desole - 14 Jul 2005 08:24 GMT
>     Look at the bytecode, and you'll see that it's very
> cheap.  The cost amounts to one unconditional jump at the
> end of the `try' clause to skip over the `catch' clause(s).
> It's possible that the JIT compiler might reorganize the
> compiled code to eliminate even that much overhead.

I can imagine.
I think that the impact on the performance is basically due to two factors:

1) exception construction (specially the stack, I believe)
2) search for an appropriate exception handler (you have to go through
the entire stack until you find one)
Thomas Schodt - 14 Jul 2005 12:04 GMT
> I think that the impact on the performance is basically due to two factors:
>
> 1) exception construction (specially the stack, I believe)

Yes, construction of the stack trace is rather expensive.

<http://java.sun.com/j2se/1.5.0/relnotes.html#hotspot>

The compiler in the server VM now provides correct stack backtraces for
all "cold" built-in exceptions. For performance purposes, when such an
exception is thrown a few times, the method may be recompiled. After
recompilation, the compiler may choose a faster tactic using
preallocated exceptions that do not provide a stack trace. To disable
completely the use of preallocated exceptions, use this new flag:
-XX:-OmitStackTraceInFastThrow.

> 2) search for an appropriate exception handler
> (you have to go through the entire stack until you find one)

Once the exception has been constructed
unrolling of the stack (and executing finally blocks)
should perform not much different from
unrolling of the stack due to return statements.
Andrea Desole - 14 Jul 2005 12:29 GMT
>> 2) search for an appropriate exception handler (you have to go through
>> the entire stack until you find one)
[quoted text clipped - 3 lines]
> should perform not much different from
> unrolling of the stack due to return statements.

Well, what I mean is that, while you are unwinding the stack and
executing finally blocks, you also have to check, at every stack frame,
if there is a catch block able to handle the exception.
But maybe you are right anyway: it shouldn't be a big difference.
Steve Wampler - 14 Jul 2005 15:28 GMT
>>> 2) search for an appropriate exception handler (you have to go through
>>> the entire stack until you find one)
[quoted text clipped - 8 lines]
> if there is a catch block able to handle the exception.
> But maybe you are right anyway: it shouldn't be a big difference.

Gaak.  I hope the JVM doesn't unroll the stack.  It should be
using a simple (internal) hash map to 'jump' directly to the
correct catch clause.  Yes, that adds a small bit to each
try block to adjust the hash map, but most of the work
for it can be done at translation time.
Steve Wampler - 14 Jul 2005 15:29 GMT
> ...I hope the JVM doesn't unroll the stack.

Oops, I meant "unwind", not unroll.  Of course the stack is
rolled back to some previous point, but shouldn't be an
unwinding process.
Steve Wampler - 14 Jul 2005 15:31 GMT
> Gaak.  I hope the JVM doesn't unroll the stack.  

Sigh.  Ignore me.  I forgot about those finally blocks,
which force some unwinding...
Andrea Desole - 14 Jul 2005 15:48 GMT
> Gaak.  I hope the JVM doesn't unroll the stack.  It should be
> using a simple (internal) hash map to 'jump' directly to the
> correct catch clause.  Yes, that adds a small bit to each
> try block to adjust the hash map, but most of the work
> for it can be done at translation time.

it's possible that I misunderstand; look at:

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Overview.doc.html#15494

After all, a map like that can be fairly hard to maintain (translation
time is probably not enough). Considering that the disadvantage is some
less performance when an exception is thrown, I think it makes sense
Ken - 14 Jul 2005 12:30 GMT
> > I think that the impact on the performance is basically due to two factors:
> >
> > 1) exception construction (specially the stack, I believe)
>
> Yes, construction of the stack trace is rather expensive.

Is this price paid at run time only when an exception is actually
thrown?   Or does simply having a try/catch block or a throw statement
in the java code cause this to happen at run time even when an
exception is not thrown?

Thanks!

Ken
Andrea Desole - 14 Jul 2005 12:33 GMT
> Is this price paid at run time only when an exception is actually
> thrown?   Or does simply having a try/catch block or a throw statement
> in the java code cause this to happen at run time even when an
> exception is not thrown?

when the exception is not thrown is not constructed, so there is no problem
John Currier - 14 Jul 2005 03:05 GMT
Eric, your "performance comparison" is slightly skewed.  The
performance characteristics of the two approaches is highly dependent
on the number of iterations and the cost of checking for the
terminating condition.  In your comparison the number of iterations
(100) times the cost of checking (i < array.length) is extremely small
compared to the cost of creating and throwing the exception.  There are
many scenarios where the opposite is true.

John
http://schemaspy.sourceforge.net
Eric Sosman - 14 Jul 2005 17:14 GMT
> Eric, your "performance comparison" is slightly skewed.  The
> performance characteristics of the two approaches is highly dependent
[quoted text clipped - 3 lines]
> compared to the cost of creating and throwing the exception.  There are
> many scenarios where the opposite is true.

   It's usually considered a good idea to quote a few
snippets from the message you're replying to, in order to
give people some context.  Keep in mind that propagation
of messages on Usenet is irregular and unsynchronized; it's
likely that some readers see your reply but do not see my
message, and have no idea what you're writing about.

   To bring people up to date: A question asked about the
performance cost of using exceptions.  I answered with a
simple illustration cribbed from "Effective Java" by Joshua
Bloch, showing two ways to loop through an array: one in
which the index is compared to the array length at each
iteration, and another where the loop simply runs until it
provokes ArrayIndexOutOfBoundsException, which is caught.
I also reported that on my machine the latter was some 15.5
times slower than the former on a 100-element array, and
invited the questioner to make his own measurements.

   Now that we're all up-to-date ...

   John, I'd be surprised to learn that there are "many
scenarios" where using exceptions for control flow is faster
than using more direct methods like `if'.  It might be possible
to concoct such a scenario, but I think it would be difficult.
Consider: if the exception reports the same circumstance that
the `if' or whatever would have tested, the code that decides
to throw the exception must itself make the same test[1].  If
the `if' made the same test, the code could discover the
condition without the overhead of creating and processing the
exception object.

   Of course, there's always the possibility of poor design.
Bloch points to Iterator.hasNext() in this regard: the method
is unnecessary in the sense that Iterator.next() will throw
NoSuchElementException when it "runs off the end," so a `try'
block could accomplish all the decision-making that hasNext()
enables.[2]  So why does hasNext() exist?  Because it's gobs
more efficient and requires less typing, that's why.  If you're
confronted with an API designed by someone who hasn't taken this
lesson to heart, an API that offers the "moral equivalent" of
next() without a matching hasNext(), you have little choice but
to use what you're given -- and curse the designer.

   Now, observe that next() must somehow make a test that's
equivalent to hasNext(), so the standard idiom for iteration
winds up making the test twice.  If that test were expensive
(which it isn't for Iterator, but let's imagine some other
API offering such a pair of methods), it's just possible that
the cost of processing an exception might be smaller than the
cost of making two tests.  My informal measurement gives some
rough idea of how expensive a test would need to be before
using exceptions became a practical alternative -- and the
answer is "very expensive indeed," more than the cost of 1500
integer-comparing `if's.  I made no claim that this measurement
was highly accurate or was universal, but I'd be comfortable
with saying that the cost of one exception lies somewhere
North of a thousand simple `if' tests.

   Yes, it's possible to write an expensive `if', most simply
by calling a few expensive methods inside it.  I suggest that
such tests are not typically associated with exceptions: you
simply don't see code that calls BigInteger.probablePrime()
and throws an exception based on the result.  (Or if you do,
you're looking at code unlike anything I've seen ...)  If you
find "many scenarios" of this sort in the code you work with,
you have my sincerest sympathy.

   [1] Or an equivalent test.  If the equivalent is cheaper
than the original, one wonders why the `if' would make the
costlier test in the first place.

   [2] Or almost.  Bloch points out that it's difficult to
distinguish the "expected" exception when next() runs off
the end from an "unexpected" exception thrown because of a
bug somewhere in code executed elsewhere with the loop.  A
simple try/catch around the whole loop lumps both together,
whereas hasNext() can easily tell the two conditions apart.

Signature

Eric.Sosman@sun.com

Steve Wampler - 14 Jul 2005 19:05 GMT
>     John, I'd be surprised to learn that there are "many
> scenarios" where using exceptions for control flow is faster
> than using more direct methods like `if'.  It might be possible
> to concoct such a scenario, but I think it would be difficult.

Simply bumping your test from an 100 element array to a 50000
element array gives one:
=====================================================
->java -version
java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode)
->cat Foo.java
import java.util.Date;

public class Foo {
   public static void main(String args[]) {
       int array[] = new int[50000];

       long t1 = new Date().getTime();
       for (int i = 0; i < array.length; ++i) {
           array[i] = i;
           }
       long t2 = new Date().getTime();

       long t3 = new Date().getTime();
       try {
           for (int i = 0; ; ++i) {
               array[i] = i;
               }
           }
       catch (ArrayIndexOutOfBoundsException ex) {}
       long t4 = new Date().getTime();

       System.out.println("T1 : "+(t2-t1)+"ms");
       System.out.println("T2 : "+(t4-t3)+"ms");
       }
   }
->javac Foo.java
->java Foo
T1 : 5ms
T2 : 1ms
=====================================================
Granted, I think it's an odd way to program, but it certainly
wasn't hard to construct...
Eric Sosman - 14 Jul 2005 19:58 GMT
>>    John, I'd be surprised to learn that there are "many
>>scenarios" where using exceptions for control flow is faster
[quoted text clipped - 6 lines]
> T1 : 5ms [for ordinary loop]
> T2 : 1ms [infinite loop with try/catch]

   Um, er, I wouldn't even time a C code construct this
way, never mind a piece of Java.  The time taken for just
one execution of a small piece of code simply isn't to be
trusted, especially not if it's the very first execution.
GC doesn't run, the JIT compiler doesn't run -- it's like
predicting someone's Marathon time by checking his crawling
speed in infancy.

   Even in my first quick-and-dirty trial, I ran each
loop a thousand times to "warm up" the JVM, then timed each
loop on one thousand, ten thousand, ... repetitions until
the ratio of times settled down.

> Granted, I think it's an odd way to program, but it certainly
> wasn't hard to construct...

   All right, you got me: I didn't think about the situation
enough.  With a 50000-element array (and with warm-ups and
repetitions as described above), using an exception is about
7% faster than making comparisons.  Specifically, I got 22855
vs. 21303 milliseconds for ten thousand repetitions of the two
loops (that's one billion array-element stores in all).  So
now we've got two rough measurements of exception-processing
overhead: one exception costs as much as somewhere between
1500 and 47000 integer comparisons.  (The wide range isn't to
be wondered at: we're just rediscovering the fact that the
derivative of 1/x is large when x is small.  Of the two
measurements, I'd place a bit more faith in the latter.)

Signature

Eric.Sosman@sun.com

Steve Wampler - 14 Jul 2005 20:19 GMT
> ..
> With a 50000-element array (and with warm-ups and
[quoted text clipped - 8 lines]
> derivative of 1/x is large when x is small.  Of the two
> measurements, I'd place a bit more faith in the latter.)

So would I, in fact, I suspect the 47000 is pretty close to
being spot on.  Increasing the array size beyond 50000 is
probably not going to show much change.  Of course, that's
also a minimal exception cost.  I'll bet the cost goes up
if the test is run in a more deeply nested call stack...
Raymond DeCampo - 14 Jul 2005 20:06 GMT
>>    John, I'd be surprised to learn that there are "many
>>scenarios" where using exceptions for control flow is faster
[quoted text clipped - 41 lines]
> Granted, I think it's an odd way to program, but it certainly
> wasn't hard to construct...

I think you will both have to work harder to prove anything.  I got
similar results when I ran the code above.  However, if I reversed the
order of the experiments, I got the opposite results:

=======================================================
$ java -version
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Client VM (build 1.5.0_03-b07, mixed mode, sharing)
$ cat Foo.java
import java.util.Date;

public class Foo {
    public static void main(String args[]) {
        int array[] = new int[50000];

        long t3 = new Date().getTime();
        try {
            for (int i = 0; ; ++i) {
                array[i] = i;
                }
            }
        catch (ArrayIndexOutOfBoundsException ex) {}
        long t4 = new Date().getTime();

        long t1 = new Date().getTime();
        for (int i = 0; i < array.length; ++i) {
            array[i] = i;
            }
        long t2 = new Date().getTime();

        System.out.println("T1 : "+(t2-t1)+"ms");
        System.out.println("T2 : "+(t4-t3)+"ms");
        }
    }
$ java -cp . Foo
T1 : 1ms
T2 : 14ms
=========================================================

Ray

Signature

XML is the programmer's duct tape.

Steve Wampler - 14 Jul 2005 20:26 GMT
> I think you will both have to work harder to prove anything.  I got
> similar results when I ran the code above.  However, if I reversed the
> order of the experiments, I got the opposite results:

Yes, my 'micro-benchmark', as Eric also points out, doesn't show
much.  Eric's latest measures are much better.
John Currier - 15 Jul 2005 01:44 GMT
Partial quote...sorry, I thought that threading newsreaders were the
norm:
>    Now, observe that next() must somehow make a test that's
> equivalent to hasNext(), so the standard idiom for iteration
[quoted text clipped - 3 lines]
> the cost of processing an exception might be smaller than the
> cost of making two tests.

I'm not sure how you can quantify the performance characteristics of
Iterator when it's an interface.

Comparing the cost of creating/throwing an exception to the cost of
making two tests is not relevant without knowing the number of
iterations.  That cost of the exception is fixed plus the cost of one
test times the number of iterations.  The alternative approach is the
cost of two tests times the number of iterations.  Which approach has
more desireable scalability characteristics?  Yes, the number of
iterations might have to be relatively high to see a benefit, but that
depends on the performance characteristics of all the pieces involved.

Note that I don't use the exception approach, but I wouldn't blindly
dismiss its appropriateness for a particular scenario.

John
Paul Bilnoski - 13 Jul 2005 17:13 GMT
> When I said that I'd prefer throwing and catching exceptions--and that,
> in fact, exceptions is the "conventional error-handling technique" in
[quoted text clipped - 3 lines]
> Do exception blocks cause big performance hits?  If so, what causes the
> hit?  Or is the person just misinformed?

The problem with exceptions in hard real-time systems is that it
introduces more invariants with respect to the expense of execution. It
becomes more difficult to make guarantees about time and memory used, so
I think that may be why it is preferred against when you can use
something conventional in simpler cases.
There may be some threshold of complexity where you opt for an exception
over checking flags or error codes.
There is a similar problem with garbage collection and making running
time more predictable that RT implementations account for.
--Paul
Robert Klemme - 13 Jul 2005 17:48 GMT
>> When I said that I'd prefer throwing and catching exceptions--and
>> that, in fact, exceptions is the "conventional error-handling
[quoted text clipped - 4 lines]
>> Do exception blocks cause big performance hits?  If so, what causes
>> the hit?  Or is the person just misinformed?

A thrown exception causes the hit.  IMHO the penalty in the normal case
(no exception thrown) is neglectible.

> The problem with exceptions in hard real-time systems is that it
> introduces more invariants with respect to the expense of execution.
[quoted text clipped - 5 lines]
> There is a similar problem with garbage collection and making running
> time more predictable that RT implementations account for.

As far as I understand the term "real time system" I wonder why someone
uses Java in the first place.  There is no such thing as guaranteed
response times etc.  So maybe the OP is dealing with a soft real time
system.

http://en.wikipedia.org/wiki/Real-time_system

Regards

   robert
Paul Bilnoski - 13 Jul 2005 17:58 GMT
>>>When I said that I'd prefer throwing and catching exceptions--and
>>>that, in fact, exceptions is the "conventional error-handling
[quoted text clipped - 28 lines]
>
>     robert

I used Java for a few real-time system programming projects in college.
We had a RT Linux kernel and the distributor also provided an RT Java VM
implementation though it was not the full language (no 1.4 NIO, no Swing).
There was also some extra functionality for the GC system to make it
handle in a more predictable way.

But to answer your point of "why use Java": because it is more
comfortable to program multithreaded applications than with some C++
threading libraries, among other things.
--Paul
Casey Hawthorne - 13 Jul 2005 18:25 GMT
Exceptions have performance penalties when thrown, only minor when not
thrown!
Depending upon how you define "minor"!

The challenge with exceptions is maintaining global state, like:
- cursor state
- timing state in real-time systems

--
Regards,
Casey
Joan - 13 Jul 2005 19:21 GMT
> Hi.  I wanted to use exceptions to handle error conditions in my code.
> I think doing that is useful, as it helps to separate "go" paths from
> error paths.  However, a coding guideline has been presented that says
> "Use conventional error-handling techniques rather than exception
> handling for straightforward local error processing in which a program
> is easily able to deal with its own errors."

The key is "easily able to deal with its own errors." If it ain't easy, use
toss/catch (if you want.)

> By "conventional error-handling," I believe they mean returning an
> error code, or just handling the error without going to a catch block.
[quoted text clipped - 10 lines]
>
> Ken
Matt Atterbury - 15 Jul 2005 04:07 GMT
I'm surprised no-one else has commented on/noticed this ...

> Hi.  I wanted to use exceptions to handle error conditions in my code.
> I think doing that is useful, as it helps to separate "go" paths from
[quoted text clipped - 10 lines]
> Java, I was told that since we have a real-time system, we can't afford
> the performance hit caused by using exceptions.

I'm confident that whatever your system is, it is _not_ real-time. Your
superiors might think it's "time-critical" or even "pseudo-real-time" but
that's as far it could go in Java as I'm pretty sure it is impossible to code
a real-time system in Java since, AFAIK, you do not have access to real-time
clocks and hardware interrupts. And, I would be absolutely amazed if you guys
even went to trouble of coding your Java program using a "true" real-time
design (but, hey, amaze away :-).

m.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.