Performance of null tests?

Discussion in 'Java' started by Adam, Nov 4, 2004.

  1. Adam

    Adam Guest

    I've just been having a discussion with a colleague and would be
    interested to hear people's opinions on which of the below code
    snippets would have the highest performance overhead.

    Assume that <do good stuff> would throw a NullPointerException if
    badger was null.

    (A)

    if(badger == null) {
    <do bad stuff>
    } else {
    <do good stuff>
    }

    (B)

    try {
    <do good stuff>
    } catch (NullPointerException npe) {
    <do bad stuff>
    }


    All help appreciated!
    Adam
    Adam, Nov 4, 2004
    #1
    1. Advertising

  2. Andrew Thompson, Nov 4, 2004
    #2
    1. Advertising

  3. Adam

    VisionSet Guest

    "Adam" <> wrote in message
    news:...
    > I've just been having a discussion with a colleague and would be
    > interested to hear people's opinions on which of the below code
    > snippets would have the highest performance overhead.
    >
    > Assume that <do good stuff> would throw a NullPointerException if
    > badger was null.
    >
    > (A)
    >
    > if(badger == null) {
    > <do bad stuff>
    > } else {
    > <do good stuff>
    > }
    >
    > (B)
    >
    > try {
    > <do good stuff>
    > } catch (NullPointerException npe) {
    > <do bad stuff>
    > }
    >
    >


    If badger is truly exceptionally null then (B) will be best because there is
    no conditional to test and there will rarely be any overhead of throwing the
    exception.
    On the other hand if badger is often null then (A) would be better since
    testing for null is very low overhead. Whilst throwing an exception is high
    overhead.

    --
    Mike W
    VisionSet, Nov 4, 2004
    #3
  4. Adam wrote:
    > I've just been having a discussion with a colleague and would be
    > interested to hear people's opinions on which of the below code
    > snippets would have the highest performance overhead.


    Answer: forget about premature optimization, write clean, understandable code.
    Using exceptions for control flow is BAD style.
    Michael Borgwardt, Nov 4, 2004
    #4
  5. Adam

    Jacob Guest

    Adam wrote:

    > (A)
    >
    > if(badger == null) {
    > <do bad stuff>
    > } else {
    > <do good stuff>
    > }
    >
    > (B)
    >
    > try {
    > <do good stuff>
    > } catch (NullPointerException npe) {
    > <do bad stuff>
    > }


    Hopefully this is an academic discussion only?

    No matter what result you get from you performance
    study, NEVER EVER write your code as in (B).
    Jacob, Nov 4, 2004
    #5
  6. Adam

    VisionSet Guest

    "VisionSet" <> wrote in message
    news:Y9qid.409$...
    >
    > "Adam" <> wrote in message
    > news:...
    > > I've just been having a discussion with a colleague and would be
    > > interested to hear people's opinions on which of the below code
    > > snippets would have the highest performance overhead.
    > >
    > > Assume that <do good stuff> would throw a NullPointerException if
    > > badger was null.
    > >
    > > (A)
    > >
    > > if(badger == null) {
    > > <do bad stuff>
    > > } else {
    > > <do good stuff>
    > > }
    > >
    > > (B)
    > >
    > > try {
    > > <do good stuff>
    > > } catch (NullPointerException npe) {
    > > <do bad stuff>
    > > }
    > >
    > >

    >
    > If badger is truly exceptionally null then (B) will be best because there

    is
    > no conditional to test and there will rarely be any overhead of throwing

    the
    > exception.
    > On the other hand if badger is often null then (A) would be better since
    > testing for null is very low overhead. Whilst throwing an exception is

    high
    > overhead.
    >


    Of course taking the wider perspective with performance aside, you should
    write code in such a way as to never need to catch RuntimeExceptions (eg
    NPE) at all. Checks such as (A) should be made to check for null where
    necessary and if at all possible disallow nulls as a precondition to a
    method by documenting and explicitly throwing NPE early.

    --
    Mike W
    VisionSet, Nov 4, 2004
    #6
  7. Adam

    Chris Smith Guest

    Jacob wrote:
    > Hopefully this is an academic discussion only?
    >
    > No matter what result you get from you performance
    > study, NEVER EVER write your code as in (B).


    Agreed that there is no reasonable circumstance where you'd cause a
    NullPointerException to be thrown and then catch it again in the same
    method. However, the general concept of choosing to allow
    NullPointerException to occur is a good one when the null input is not
    expected.

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

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Nov 4, 2004
    #7
  8. "VisionSet" <> schreef in bericht
    news:Y9qid.409$...
    >
    > "Adam" <> wrote in message
    > news:...
    >> I've just been having a discussion with a colleague and would be
    >> interested to hear people's opinions on which of the below code
    >> snippets would have the highest performance overhead.
    >>
    >> Assume that <do good stuff> would throw a NullPointerException if
    >> badger was null.
    >>
    >> (A)
    >>
    >> if(badger == null) {
    >> <do bad stuff>
    >> } else {
    >> <do good stuff>
    >> }
    >>
    >> (B)
    >>
    >> try {
    >> <do good stuff>
    >> } catch (NullPointerException npe) {
    >> <do bad stuff>
    >> }
    >>
    >>

    >
    > If badger is truly exceptionally null then (B) will be best because
    > there is no conditional to test and there will rarely be any overhead
    > of throwing the exception.
    > On the other hand if badger is often null then (A) would be better
    > since testing for null is very low overhead. Whilst throwing an
    > exception is high overhead.


    In other words: it depends. It depends on the chance of an exception occuring
    and the performance difference between the approaches.
    Boudewijn Dijkstra, Nov 4, 2004
    #8
  9. Adam

    Eric Sosman Guest

    Boudewijn Dijkstra wrote:
    > "VisionSet" <> schreef in bericht
    > news:Y9qid.409$...
    >
    >>"Adam" <> wrote in message
    >>news:...
    >>
    >>>I've just been having a discussion with a colleague and would be
    >>>interested to hear people's opinions on which of the below code
    >>>snippets would have the highest performance overhead.
    >>>
    >>>Assume that <do good stuff> would throw a NullPointerException if
    >>>badger was null.
    >>>
    >>>(A)
    >>>
    >>>if(badger == null) {
    >>> <do bad stuff>
    >>>} else {
    >>> <do good stuff>
    >>>}
    >>>
    >>>(B)
    >>>
    >>>try {
    >>> <do good stuff>
    >>>} catch (NullPointerException npe) {
    >>> <do bad stuff>
    >>>}
    >>>
    >>>

    >>
    >>If badger is truly exceptionally null then (B) will be best because
    >>there is no conditional to test and there will rarely be any overhead
    >>of throwing the exception.
    >>On the other hand if badger is often null then (A) would be better
    >>since testing for null is very low overhead. Whilst throwing an
    >>exception is high overhead.

    >
    >
    > In other words: it depends. It depends on the chance of an exception occuring
    > and the performance difference between the approaches.


    The `if' will probably turn into just a few instructions
    once the JIT gets through with it -- ten instructions seems
    high, but let's just suppose it's ten. We're working on the
    back of the envelope here, okay?

    Creating and catching the exception will take a variable
    amount of work depending on how deep the stack happens to be,
    but let's be optimistic and suppose it takes only ten thousand
    instructions, including the eventual cost of garbage collecting
    the NullPointerException object after it's been discarded.

    Under these suppositions, one exception carries the time
    penalty of a thousand `if' tests. Using an exception to avoid
    the `if' would be a win if the reference is null less than one
    thousandth of the time, non-null more than 99.9% of the time.

    How much of a gain can you get? Let's suppose the reference
    is null just one ten-thousandth of the time, one tenth of the
    break-even point. If the code executes a million times, you'll
    throw one hundred exceptions at a (supposed) cost of one million
    instructions. Meanwhile, you've avoided (supposedly) ten million
    instructions for the `if' tests you didn't make. The gain is
    nine million instructions, which sounds pretty good.

    But how good is it, really? Well, processors vary and
    caches vary and memory speeds vary and blah blah blah, but
    let's be pessimistic and assume you can execute instructions
    at a rate of only 1GHz. You have saved nine milliseconds.

    Nine whole milliseconds.

    nine
    thousandths
    of
    one
    second

    You have klutzed up your code, and even under the most
    optimistic assumptions imaginable a million executions of
    the "optimized" version have saved you

    nine
    thousandths
    of
    one
    second

    That's roughly the amount of time between successive
    wave crests of the note on the bottom line of the bass clef,
    two octaves below concert A.

    nine
    thousandths
    of
    one
    second

    It's about two-thirds the time of one CRT refresh.

    nine
    thousandths
    of
    one
    second

    It's enough time for a race car going 200 miles/hour
    to travel thirty-two inches.

    nine
    thousandths
    of
    one
    second

    Let me ask you this: What are you going to do with all
    that extra time? Won't it hang heavy on your hands?

    --
    Eric Sosman, Nov 4, 2004
    #9
  10. Adam

    Chris Uppal Guest

    Eric Sosman wrote:

    > Let me ask you this: What are you going to do with all
    > that extra time? Won't it hang heavy on your hands?


    Beautifully put (including the rest that I snipped).

    I think part of the problem is that we daily use machines that expend /HUGE/
    amounts of processing power to do even the simplest of tasks (I'd hate to know
    how long the execution path is for pressing one key in OE as I type this; and I
    shudder to think what the code path is like for clicking a button in Eclipse --
    it must be in 100's of millions to billions range, judging by the treacly way
    it responds). One effect of that is that we forget how frighteningly fast our
    machines are.

    It makes it difficult to form (or maintain) an intuitive sense of what's cheap
    and what's expensive -- or a usefully accurate one anyway.

    "Wanna save a second ? OK which /billion/ instructions are you not going to
    execute ?"

    -- chris
    Chris Uppal, Nov 5, 2004
    #10
  11. Adam

    Adam Guest

    Wow - that's a lot of responses, cheers everyone!

    That is what I suspected and our next step will be to evaluate a load
    of different points in the code with this in mind. Based on the
    likelihood of a null scenario!

    Just to give a bit of context, this is part of a server side method
    called heavily by a multitude of clients - ergo performance is
    paramount, easily readable code can be sacrificied (but mitigated with
    verbose comments, one hopes).

    And no, I'm not a student ;)
    Adam, Nov 5, 2004
    #11
  12. Adam

    steve Guest

    On Sat, 6 Nov 2004 01:14:02 +0800, Adam wrote
    (in article <>):

    > Wow - that's a lot of responses, cheers everyone!
    >
    > That is what I suspected and our next step will be to evaluate a load
    > of different points in the code with this in mind. Based on the
    > likelihood of a null scenario!
    >
    > Just to give a bit of context, this is part of a server side method
    > called heavily by a multitude of clients - ergo performance is
    > paramount, easily readable code can be sacrificied (but mitigated with
    > verbose comments, one hopes).
    >
    > And no, I'm not a student ;)


    For good code design you should not be using exceptions , to do "if",
    "while","case" processing.

    There is a very good article on the sun java site , called ( i think) "use &
    abuse of exceptions"
    Your "use" sun classes as serious "abuse", but they also go indepth as to
    why you should not do it (giving timings etc. basically when you cause an
    exception you are creating an object each time it occurs), and it is very
    expensive in time.

    Finally if it is server side code ( and considering your user load) ,
    consider , the operation of generating thousands of exceptions, both on
    memory & time.
    Eeeewwwww!!. :)

    steve
    steve, Nov 6, 2004
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kivak Wolf
    Replies:
    2
    Views:
    10,059
    Kivak Wolf
    Jun 28, 2005
  2. Replies:
    8
    Views:
    881
  3. Replies:
    5
    Views:
    26,505
    Mike Schilling
    Mar 29, 2006
  4. Brian
    Replies:
    3
    Views:
    1,232
  5. dayo
    Replies:
    11
    Views:
    329
    Ilya Zakharevich
    Dec 16, 2005
Loading...

Share This Page