how slow is exceptions really compared?

Discussion in 'Java' started by tom fredriksen, Feb 16, 2006.

  1. I was reading about exceptions and in the book "Effective Java" it is
    stated that exceptions are terribly slow, about 79 times slower than the
    FAST example below. Now i tested it and I cant see any difference. I
    have heard this many times, but I am not sure how much I believe it. So
    what is it that i so slow about exception. I understand that creating an
    exception object is slow and sending it up the stack for processing at
    every point is also slow. But as far as I can see that would only matter
    if you used eceptions for flow control (i.e. for every iteration (for
    some strange reason) or something similar). I dont see how it can be any
    slower to use it as described in the SLOW code below (I know it is not
    the correct way to do it, idiom wise). Any comments?

    /tom

    SLOW

    try {
    int i = 0;
    while(true)
    a[i++].f();
    } catch(ArrayIndexOutOfBoundsException e) {
    }


    FAST:

    for (int i = 0; i < a.length; i++)
    a.f();
    tom fredriksen, Feb 16, 2006
    #1
    1. Advertising

  2. tom fredriksen

    Timo Stamm Guest

    tom fredriksen schrieb:
    >
    > I was reading about exceptions and in the book "Effective Java" it is
    > stated that exceptions are terribly slow


    This has been true in early versions of java.


    > But as far as I can see that would only matter
    > if you used eceptions for flow control (i.e. for every iteration (for
    > some strange reason) or something similar).


    Exceptions are ment to handle exceptional control flow. Using them for
    conventional flow control is bad design. So even if Exceptions were
    still as slow as they have been five years ago, it should not not really
    matter.


    "Effective Java" doesn't seem to be a recommendable book.


    Timo
    Timo Stamm, Feb 17, 2006
    #2
    1. Advertising

  3. "tom fredriksen" <> wrote in message
    news:...
    >
    > I was reading about exceptions and in the book "Effective Java" it is
    > stated that exceptions are terribly slow, about 79 times slower than the
    > FAST example below. Now i tested it and I cant see any difference. I have
    > heard this many times, but I am not sure how much I believe it. So what is
    > it that i so slow about exception. I understand that creating an exception
    > object is slow and sending it up the stack for processing at every point
    > is also slow. But as far as I can see that would only matter if you used
    > eceptions for flow control (i.e. for every iteration (for some strange
    > reason) or something similar). I dont see how it can be any slower to use
    > it as described in the SLOW code below (I know it is not the correct way
    > to do it, idiom wise). Any comments?
    >
    > /tom
    >
    > SLOW
    >
    > try {
    > int i = 0;
    > while(true)
    > a[i++].f();
    > } catch(ArrayIndexOutOfBoundsException e) {
    > }
    >
    >
    > FAST:
    >
    > for (int i = 0; i < a.length; i++)
    > a.f();


    If you're timing the running of programs that do nothing but that code, you
    won't see much difference, since the startup cost dwarfs everything else.

    Try this test:

    class Timing
    {
    public static void main(String[] args) throws Exception
    {
    int[] a = new int[10];

    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++)
    {
    try
    {
    int j = 0;
    while(true)
    {
    a[j] = j;
    j++;
    }
    }
    catch(ArrayIndexOutOfBoundsException e)
    {
    }
    }
    System.out.println(
    "Slow time is " + (System.currentTimeMillis() - start) +
    " milliseconds.");

    start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++)
    {
    for (int j = 0; j < 10; j++)
    {
    a[j] = j;
    }
    }
    System.out.println(
    "Fast time is " + (System.currentTimeMillis() - start) +
    " milliseconds.");
    }
    }

    I get output like

    Slow time is 6843 milliseconds.
    Fast time is 63 milliseconds.
    Mike Schilling, Feb 17, 2006
    #3
  4. "Timo Stamm" <> wrote in message
    news:43f5190e$0$13598$-online.net...

    >
    > "Effective Java" doesn't seem to be a recommendable book.


    Are you kidding? It's one of the best Java books ever written. It's true
    that it could stand updating, as some of the details are no longer accurate,
    but overall it's check-full of good advice. In fact, the instructor at a
    Microsoft course I once took called in the best C# book he knew of, because
    so much of it is also applicable to .NET.
    Mike Schilling, Feb 17, 2006
    #4
  5. tom fredriksen

    Timo Stamm Guest

    Mike Schilling schrieb:
    > I get output like
    >
    > Slow time is 6843 milliseconds.
    > Fast time is 63 milliseconds.



    I get output like

    Slow time is 65 milliseconds.
    Fast time is 49 milliseconds.

    (Run on a 4 processor 64 bit machine, so server vm is enabled by default
    and the JIT kicks in.)


    Micro-optimizations like using your own constructs instead of Exceptions
    are a total waste of time. Even worse, they make the code difficult to
    maintain.


    Timo
    Timo Stamm, Feb 17, 2006
    #5
  6. "Timo Stamm" <> wrote in message
    news:43f5246d$0$13607$-online.net...
    > Mike Schilling schrieb:
    >> I get output like
    >>
    >> Slow time is 6843 milliseconds.
    >> Fast time is 63 milliseconds.

    >
    >
    > I get output like
    >
    > Slow time is 65 milliseconds.
    > Fast time is 49 milliseconds.
    >
    > (Run on a 4 processor 64 bit machine, so server vm is enabled by default
    > and the JIT kicks in.)
    >
    >
    > Micro-optimizations like using your own constructs instead of Exceptions
    > are a total waste of time. Even worse, they make the code difficult to
    > maintain.


    Using a for loop to navigate through an array is "my own construct" and a
    "micro-optimization" that's "hard to maintain"? Good Lord.
    Mike Schilling, Feb 17, 2006
    #6
  7. tom fredriksen

    Timo Stamm Guest

    Mike Schilling schrieb:
    > "Timo Stamm" <> wrote in message
    > news:43f5190e$0$13598$-online.net...
    >
    >> "Effective Java" doesn't seem to be a recommendable book.

    >
    > Are you kidding? It's one of the best Java books ever written.


    I haven't read it, but what Tom reported sounded a lot like propagation
    of micro-optimizations.


    Timo
    Timo Stamm, Feb 17, 2006
    #7
  8. "Timo Stamm" <> wrote in message
    news:43f5272d$0$13593$-online.net...
    > Mike Schilling schrieb:
    >> "Timo Stamm" <> wrote in message
    >> news:43f5190e$0$13598$-online.net...
    >>
    >>> "Effective Java" doesn't seem to be a recommendable book.

    >>
    >> Are you kidding? It's one of the best Java books ever written.

    >
    > I haven't read it, but what Tom reported sounded a lot like propagation of
    > micro-optimizations.


    Do you often judge books by second-hand reports of small sections of them?

    Just asking.
    Mike Schilling, Feb 17, 2006
    #8
  9. tom fredriksen

    Roedy Green Guest

    On Fri, 17 Feb 2006 00:41:13 +0100, tom fredriksen <>
    wrote, quoted or indirectly quoted someone who said :

    >Now i tested it and I cant see any difference.

    The problem is compilers/JITs/AOTs are getting smarter. They easily
    ultra- optimise contrived examples they could not tidy up in real
    world situations.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
    Roedy Green, Feb 17, 2006
    #9
  10. tom fredriksen

    Timo Stamm Guest

    Mike Schilling schrieb:
    > "Timo Stamm" <> wrote in message
    > news:43f5246d$0$13607$-online.net...
    >> Mike Schilling schrieb:
    >>> I get output like
    >>>
    >>> Slow time is 6843 milliseconds.
    >>> Fast time is 63 milliseconds.

    >>
    >> I get output like
    >>
    >> Slow time is 65 milliseconds.
    >> Fast time is 49 milliseconds.
    >>
    >> (Run on a 4 processor 64 bit machine, so server vm is enabled by default
    >> and the JIT kicks in.)
    >>
    >>
    >> Micro-optimizations like using your own constructs instead of Exceptions
    >> are a total waste of time. Even worse, they make the code difficult to
    >> maintain.

    >
    > Using a for loop to navigate through an array is "my own construct" and a
    > "micro-optimization" that's "hard to maintain"?


    Obviously not. Are you trolling? Here is an explanation for the interested:

    A "micro-optimization" is a performance optimization at a low level. For
    example, the following construct:

    for( int i = upperbound; 0 != i--; ) {
    // ...
    }

    is supposed to be more efficient than

    for( int i = 0; i < upperbound; i++ ) {
    // ...
    }


    This is actually true, the former construct can be more efficient in
    statically compiled languages. But in a language like Java, which is
    compiled into byte code and interpreted by a virtual machine that can
    theoretically run on any platform, such optimizations don't make much
    sense for several reasons:

    The latter construct is standard - every programmer who knows languages
    influenced by C will understand it at the first glance. Using your own
    constructs will make the code harder to read for anybody else, which may
    lead to more time-consuming maintenance and more bugs.

    Additionally, you can not even be sure that this micro-optimization even
    gained you any performance, because the Java VM has a just-in-time
    compiler that works under the assumption that you wrote plain java code.
    If this JIT compiler recognizes standard for loops and optimizes them,
    you might even loose performance.

    The same goes for assumptions about a lot of other constructs, about
    memory management, etc.

    Those optimizations have one thing in common: They are not made because
    a programm runs too slow. They are premature. Donald Knuth said "We
    should forget about small efficiencies, say about 97% of the time:
    premature optimization is the root of all evil."

    So you should never waste any time on optimization unless you have made
    tests, clearly identified the bottleneck, and are able to change your
    design accordingly. I am sure it will almost never be the for loop you
    have to optimize.


    Back to the original topic: Tom posted two variants of looping through
    an array:


    | SLOW
    |
    | try {
    | int i = 0;
    | while(true)
    | a[i++].f();
    | } catch(ArrayIndexOutOfBoundsException e) {
    | }
    |
    |
    | FAST:
    |
    | for (int i = 0; i < a.length; i++)
    | a.f();


    If this is taken from the book "Effective Java", I don't understand the
    point the author is trying to make. The assumption that using Exceptions
    this way is _much_ slower than the standard way is wrong. I see that the
    book might be older than the JVM JIT Compiler, but this just proves that
    you shouldn't make too much assumptions when you are writing for a JVM
    whose implementation might change. (BTW: this is a very poor example for
    JIT testing, because it will probably never appear in real world code.)

    What really irritated is that there was no mention of any other argument
    why the slow version is a bad idea other than that it is slower. I
    consider the slow version to be a violation of the concept of exceptions
    because they are used for standard control flow. This outweighs any
    performance issues by far, imho.


    | Do you often judge books by second-hand reports of small sections of
    | them?
    |
    | Just asking.

    I really didn't want to judge the book without having read it myself.
    But it still doesn't seems to be worth trying out from what I have see
    until now.

    It isn't unlikely that this was all taken out of context, or that the
    book has much better information to offer on other topics. If you have
    any valuable information about the book to add, I would appreciate to
    hear about it.


    Tim
    Timo Stamm, Feb 17, 2006
    #10
  11. Timo Stamm wrote:
    > tom fredriksen schrieb:
    >>
    >> I was reading about exceptions and in the book "Effective Java" it is
    >> stated that exceptions are terribly slow

    >
    > This has been true in early versions of java.


    And later versions. There are some specific cases were some JVMs will
    optimise. You'd be foolish to rely on them. Perhaps for some reason the
    next update release fails to inline one of your methods. Then your code
    isn't just a little slow.

    Here's a set of timings for Mike's code:

    & /usr/java/jdk1.5.0_05/bin/java Timing
    Slow time is 107630 milliseconds.
    Fast time is 453 milliseconds.

    Presumably the performance difference would be far worse if there were a
    realistic number of frames on the stack.

    I wouldn't want to be responsible for something like that to happen on a
    live customer system.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Feb 17, 2006
    #11
  12. tom fredriksen

    Jens Auer Guest

    Timo Stamm wrote:
    > Mike Schilling schrieb:
    >> "Timo Stamm" <> wrote in message
    >> news:43f5246d$0$13607$-online.net...
    >>> Mike Schilling schrieb:
    >>>> I get output like
    >>>>
    >>>> Slow time is 6843 milliseconds.
    >>>> Fast time is 63 milliseconds.
    >>>
    >>> I get output like
    >>>
    >>> Slow time is 65 milliseconds.
    >>> Fast time is 49 milliseconds.
    >>>
    >>> (Run on a 4 processor 64 bit machine, so server vm is enabled by
    >>> default and the JIT kicks in.)
    >>>
    >>>
    >>> Micro-optimizations like using your own constructs instead of
    >>> Exceptions are a total waste of time. Even worse, they make the code
    >>> difficult to maintain.

    >>
    >> Using a for loop to navigate through an array is "my own construct"
    >> and a "micro-optimization" that's "hard to maintain"?

    >
    > Obviously not. Are you trolling? Here is an explanation for the interested:
    >
    > A "micro-optimization" is a performance optimization at a low level. For
    > example, the following construct:
    >
    > for( int i = upperbound; 0 != i--; ) {
    > // ...
    > }
    >
    > is supposed to be more efficient than
    >
    > for( int i = 0; i < upperbound; i++ ) {
    > // ...
    > }
    >
    >
    > This is actually true, the former construct can be more efficient in
    > statically compiled languages. But in a language like Java, which is
    > compiled into byte code and interpreted by a virtual machine that can
    > theoretically run on any platform, such optimizations don't make much
    > sense for several reasons:

    If seen the former variant quite often in JDK source code (eg BitSet
    implementation of and), but don't understand why this should be faster.
    Both do the same number of instructions, with the difference of adding
    and substraction. Can you explain why the first one is better to
    optimize, or just give me a web-page explaining this?
    Jens Auer, Feb 17, 2006
    #12
  13. Timo Stamm wrote:
    > A "micro-optimization" is a performance optimization at a low level. For
    > example, the following construct:
    >
    > for( int i = upperbound; 0 != i--; ) {
    > // ...
    > }
    >
    > is supposed to be more efficient than
    >
    > for( int i = 0; i < upperbound; i++ ) {
    > // ...
    > }
    >
    >
    > This is actually true, the former construct can be more efficient in
    > statically compiled languages. But in a language like Java, which is
    > compiled into byte code and interpreted by a virtual machine that can
    > theoretically run on any platform, such optimizations don't make much
    > sense for several reasons:


    Actually, this is not true. Any modern compiler optimises such details
    away, in most cases both statements are compiled into the same
    assembler/bytecode. What the statement really is, is syntactic sugar, or
    lazy coding. Its quicker to write or its perceived as more "smart" than
    other code. You choose... One should really stick to known and simple
    idioms, so that it is easier to maintain the code by others and dont
    increase the change of introducing bugs.

    Btw, the correct syntax for this idiom is:

    for ( int i = upperbound; i--; ) // i-- is false when it reaches 0


    > Back to the original topic: Tom posted two variants of looping through
    > an array:
    >
    >
    > | SLOW
    > |
    > | try {
    > | int i = 0;
    > | while(true)
    > | a[i++].f();
    > | } catch(ArrayIndexOutOfBoundsException e) {
    > | }
    > |
    > |
    > | FAST:
    > |
    > | for (int i = 0; i < a.length; i++)
    > | a.f();
    >
    >
    > If this is taken from the book "Effective Java", I don't understand the
    > point the author is trying to make. The assumption that using Exceptions
    > this way is _much_ slower than the standard way is wrong.


    This was my point as well. the two code bits do not cause the SLOW code
    to go 80 times slower, hence the original question. But as stated in
    another post, creating an outer loop for these two statements would
    increase overhead of them and then one would see the difference. So why
    did he not include that in the book.

    > What really irritated is that there was no mention of any other argument
    > why the slow version is a bad idea other than that it is slower. I
    > consider the slow version to be a violation of the concept of exceptions
    > because they are used for standard control flow. This outweighs any
    > performance issues by far, imho.


    He did mention that and so did I in the original post.

    /tom
    tom fredriksen, Feb 17, 2006
    #13
  14. Mike Schilling wrote:
    > If you're timing the running of programs that do nothing but that code, you
    > won't see much difference, since the startup cost dwarfs everything else.


    I only timed the two statements, what I did not do was add the outer
    loop, since he did not mention it in the example. Thats what baffled me.
    So in essence this is proof enough. It is creating the exceptions and
    traversing the stack that takes time. But since exceptions should never
    be used to control the flow of logic, the argument that "exceptions are
    slow, dont use it as much" is really not the point then, and hence
    ill-advised.

    /tom
    tom fredriksen, Feb 17, 2006
    #14
  15. tom fredriksen

    Daniel Dyer Guest

    On Fri, 17 Feb 2006 06:43:40 -0000, Timo Stamm <> wrote:
    > If this is taken from the book "Effective Java", I don't understand the
    > point the author is trying to make. The assumption that using Exceptions
    > this way is _much_ slower than the standard way is wrong. I see that the
    > book might be older than the JVM JIT Compiler, but this just proves that
    > you shouldn't make too much assumptions when you are writing for a JVM
    > whose implementation might change. (BTW: this is a very poor example for
    > JIT testing, because it will probably never appear in real world code.)
    >
    > What really irritated is that there was no mention of any other argument
    > why the slow version is a bad idea other than that it is slower. I
    > consider the slow version to be a violation of the concept of exceptions
    > because they are used for standard control flow. This outweighs any
    > performance issues by far, imho.


    This is exactly the point that Bloch is making in Effective Java. The two
    examples come from "Item 39: Use exceptions only for exceptional
    conditions" and the first is preceeded by the comment "Horrible abuse of
    exceptions. Don't ever do this!". The discussion of performance is just
    a rebuttal of the argument that using exceptions in this way would be
    quicker by avoiding termination test for each iteration of the loop.

    > | Do you often judge books by second-hand reports of small sections of
    > | them?
    > |
    > | Just asking.
    >
    > I really didn't want to judge the book without having read it myself.
    > But it still doesn't seems to be worth trying out from what I have see
    > until now.


    I agree with Mike's assessment of the book. And it's not just the two of
    us, it is widely regarded as the best book ever written on Java
    programming. There are a few tips, such as the type-safe enum pattern,
    that are obsoleted by Java 5 features, but it is still well worth reading.

    > It isn't unlikely that this was all taken out of context, or that the
    > book has much better information to offer on other topics. If you have
    > any valuable information about the book to add, I would appreciate to
    > hear about it.


    Check-out the reviews on Amazon, or search the Google Groups archive for
    mentions of it on this group.

    Dan.

    --
    Daniel Dyer
    http://www.dandyer.co.uk
    Daniel Dyer, Feb 17, 2006
    #15
  16. tom fredriksen

    Roedy Green Guest

    Why for i-- is faster than for i++

    On Fri, 17 Feb 2006 10:10:45 +0100, Jens Auer
    <> wrote, quoted or indirectly quoted
    someone who said :

    >If seen the former variant quite often in JDK source code (eg BitSet
    >implementation of and), but don't understand why this should be faster.
    >Both do the same number of instructions, with the difference of adding
    >and substraction. Can you explain why the first one is better to
    >optimize, or just give me a web-page explaining this?


    The short answer is computers have shortcuts to compare with 0 that
    are faster than comparing with N. When you go down in a for loop,
    under the hood, you determine loop termination by comparing the index
    with 0, and with N when going up.

    Up loops are particularly painful if N gets recomputed each time round
    the loop, e.g. ArrayList.size(). Happily 0, the termination value,
    when you work down never get recomputed.

    To explain a little more deeply, here is a quick course in Intel
    assembler.

    [add-register] is a single instruction that adds two 32-bit registers
    a and b and leaves the result in a. As a side effect it sets a magic
    register called the condition code that records whether the result was
    positive, negative, zero, overflowed etc. You get this information
    for free as a side effect of an arithmetic instruction.

    So if you said something like this in Java,

    boolean biggerThanZero = ( a - b ) > 0;

    you can in a sense, you do the whole thing in one machine instruction,
    [sub-register] that takes only one clock cycle.

    if you wrote

    if ( ( a - b ) > 0 ) // or almost equivalently if ( a > b )
    {
    dothis();
    }
    else
    {
    dothat();
    }


    the if part compiles to two machine instructions like this:
    [subtract] a, b
    [jump if result <= 0] to else code

    Typically the conditional jump is much faster when it falls through to
    the if code than when it jumps to jump to the else clause. It barrels
    along where it was planning to go anyway, rather than taking a detour,
    throwing a monkey wrench into its plans for the future. The
    conditional jump just interrogates the pre-computed magic condition
    code register which we got free as a side effect of the subtract.

    Now lets have a look at the code in an i++ style loop.

    I am explaining the principle, not the Intel architecture, so I feel
    free to lie slightly for the sake of simplicity.

    i++ is done with an [increment] instruction that adds 1 in a single
    cycle.

    Then you do a compare instruction with N, which sets the condition
    code. A compare is like a subtract, except you discard the result and
    it works even when there is overflow, and it also provides both signed
    and unsigned comparison results in the condition code register. Then
    you do a conditional jump out of the loop. Otherwise you fall though
    and execute the loop body one more time.

    So, for looping UP a total 3 instructions, with a nice fall-through on
    the conditional jump in the more common case.

    Now lets say you count down. You subtract 1. As a side effect you get
    the condition code telling you if the result is +ve, 0 or -ve.
    You do a conditional jump out of the loop if it has gone negative.

    So, for looping DOWN, a total of 2 instructions with a nice
    fall-through on the usual case conditional jump.

    People familiar with Intel assembler will chime that the [decrement]
    instruction fails to set the condition code. You can subtract one, in
    one cycle too, not using the [decrement] instruction, using [subtract]
    with a register containing a convenient one, or subtract literal 1,
    which DOES set the condition code. (Much of my dicey coding in 8086
    assembler for the BBL Forth engine revolved around always having a
    convenient 1 sitting in a register somewhere to use for a
    condition-code setting increment or decrement.)

    This one cycle overhead penalty for upward counted loops is only going
    to matter on a very short loop body. Further it could be offset by
    preemptive RAM caching hardware that presumes you generally work up.

    Other factors in loop optimisation: If the loop body is small enough,
    it may be cached totally on the CPU chip greatly increasing its speed.
    So oddly, it sometimes pays to break a loop up in to two shorter
    passes, running over all the elements twice. This is all complicated
    immensely by how ram for operands and code is cached and preemptively
    cached. Nowadays all you can do is code it several ways and see which
    works faster. Jet, an AOT compiler, does versioning, creating multiple
    loop bodies, each with a different set of presumptions. It decides at
    the top of the loop which body to use, so it does not have to test
    conditions repeatedly as it goes through the loop body.


    E.g. Jet would convert code like this:

    for ( i=0; i<n; i++ )
    {
    if ( i mod 2 != 0 )
    {
    dothing1();
    }
    else
    {
    dothing2();
    }
    sum += i;
    if ( i mod 2 != 0 )
    {
    dothing3();
    }
    else
    {
    dothing4();
    }
    }

    to code like this:


    for ( i=0; i<n; i++ )
    {
    if ( i & 1 != 0)
    {
    dothing1();
    sum += i;
    do1thing3();
    }
    else
    {
    dothing2();
    sum += i;
    dothing4();
    }
    }

    or maybe even code like this if side effects can be proved the same.

    for ( i=1; i<n; i+=2; )
    {
    dothing1();
    sum += i;
    do1thing3();
    }
    for ( i=0; i<n; i+=2 )
    {
    dothing2();
    sum += i;
    dothing4();
    }
    }









    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
    Roedy Green, Feb 17, 2006
    #16
  17. tom fredriksen

    Roedy Green Guest

    On Fri, 17 Feb 2006 10:14:11 +0100, tom fredriksen <>
    wrote, quoted or indirectly quoted someone who said :

    >for ( int i = upperbound; i--; ) // i-- is false when it reaches 0


    You are thinking in C. i-- does not evaluate to a boolean, and
    further you continue the loop one more time when i==0. You stop only
    when it goes negative.

    I think this it what you meant to say

    for ( int i = n; --i >= 0; )
    or
    for ( int i =n-1; i >= 0; i-- )

    The problem is programmers are not familiar with these idiom and won't
    be able to tell easily what the actual range of indexes is and where
    the code comes out in the wash when n= 0.

    It is not immediately obvious you are iterating n-1 .. 0 as it is when
    you use the canonical familiar form:

    for ( int i = 0 ; i<n; i++)

    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
    Roedy Green, Feb 17, 2006
    #17
  18. tom fredriksen wrote:
    >
    > Btw, the correct syntax for this idiom is:
    >
    > for ( int i = upperbound; i--; ) // i-- is false when it reaches 0


    That isn't even legal Java.



    There is a bug in Sun's HotSpot that tends to make downward loops slower.

    Tom Hawitn
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Feb 17, 2006
    #18
  19. tom fredriksen

    Jens Auer Guest

    Re: Why for i-- is faster than for i++

    Roedy Green wrote:
    .... Some very nice explaination

    Thank you for this informative post. I immediately made a little test
    program out of the previously posted code to test the loop-variants:
    class Timing
    {
    public static void f1(int[] a) {
    for (int i=1000000; 0 != i--;)
    for (int j=9; 0 <= j; --j)
    a[j] = j;
    }

    public static void f2(int[] a) {
    for (int i = 0; i != 1000000; ++i)
    {
    for (int j = 0; j != 10; ++j)
    {
    a[j] = j;
    }
    }
    }

    public static void main(String[] args) throws Exception
    {
    int[] a = new int[10];
    final int runs = Integer.valueOf(args[0]);

    long start = System.currentTimeMillis();
    for (int i=0; i != runs; i++)
    f1(a);
    System.out.println(
    "Slow time is " + (System.currentTimeMillis() - start) +
    " milliseconds.");

    start = System.currentTimeMillis();
    for (int i=0; i != runs; i++)
    f2(a);
    System.out.println(
    "Fast time is " + (System.currentTimeMillis() - start) +
    " milliseconds.");
    }
    }

    With the normal JDK 5.0 virtual machine, both loops seem to perform more
    or less equally fast:
    auer@lsi-08:~/tmp$ java Timing 1
    Slow time is 32 milliseconds.
    Fast time is 34 milliseconds.
    auer@lsi-08:~/tmp$ java Timing 100
    Slow time is 3047 milliseconds.
    Fast time is 3025 milliseconds.
    auer@lsi-08:~/tmp$ java Timing 1000
    Slow time is 30072 milliseconds.
    Fast time is 30206 milliseconds.

    But using the -server jit compiler, the incrementing loop outperforms
    the decrementing:
    auer@lsi-08:~/tmp$ java -server Timing 1
    Slow time is 38 milliseconds.
    Fast time is 42 milliseconds.
    auer@lsi-08:~/tmp$ java -server Timing 100
    Slow time is 1636 milliseconds.
    Fast time is 1078 milliseconds.
    auer@lsi-08:~/tmp$ java -server Timing 1000
    Slow time is 14821 milliseconds.
    Fast time is 10360 milliseconds.

    Measuring is done with Sun JDK 5.0:
    java version "1.5.0_06"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
    Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)

    It seems that the Sun JIT is more optimized to incrementing case, but I
    don't see nay documentation which optimization the JIT does and when
    they are applied, which I find very annoying.
    Jens Auer, Feb 17, 2006
    #19
  20. Roedy Green wrote:
    > On Fri, 17 Feb 2006 10:14:11 +0100, tom fredriksen <>
    > wrote, quoted or indirectly quoted someone who said :
    >
    >> for ( int i = upperbound; i--; ) // i-- is false when it reaches 0

    >
    > You are thinking in C.


    Fair enough, i thought I had written a statement like that a couple of
    days ago, but that was all in my mind.

    /tom
    tom fredriksen, Feb 17, 2006
    #20
    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. Replies:
    3
    Views:
    3,012
  2. Ike

    Slow compared to php

    Ike, Aug 11, 2004, in forum: Java
    Replies:
    7
    Views:
    522
  3. Kevin
    Replies:
    16
    Views:
    923
    Chris Uppal
    Feb 12, 2006
  4. rtilley

    Is python very slow compared to C

    rtilley, Feb 11, 2006, in forum: Python
    Replies:
    51
    Views:
    1,013
  5. Mat Schaffer

    String#chop slow? REALLY slow?

    Mat Schaffer, Jul 27, 2006, in forum: Ruby
    Replies:
    11
    Views:
    321
    Caio Chassot
    Jul 27, 2006
Loading...

Share This Page