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 / February 2006

Tip: Looking for answers? Try searching our database.

how slow is exceptions really compared?

Thread view: 
tom fredriksen - 16 Feb 2006 23:41 GMT
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[i].f();
Timo Stamm - 17 Feb 2006 00:30 GMT
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
Mike Schilling - 17 Feb 2006 00:58 GMT
> "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.
Timo Stamm - 17 Feb 2006 01:30 GMT
Mike Schilling schrieb:

>> "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
Mike Schilling - 17 Feb 2006 01:52 GMT
> Mike Schilling schrieb:
>>
[quoted text clipped - 4 lines]
> 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.
Thomas Hawtin - 17 Feb 2006 08:25 GMT
> 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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Mike Schilling - 17 Feb 2006 00:43 GMT
> 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
[quoted text clipped - 23 lines]
> for (int i = 0; i < a.length; i++)
>     a[i].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.
Timo Stamm - 17 Feb 2006 01:18 GMT
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
Mike Schilling - 17 Feb 2006 01:29 GMT
> Mike Schilling schrieb:
>> I get output like
[quoted text clipped - 13 lines]
> 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.
Timo Stamm - 17 Feb 2006 06:43 GMT
Mike Schilling schrieb:
>> Mike Schilling schrieb:
>>> I get output like
[quoted text clipped - 16 lines]
> 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
|
[quoted text clipped - 9 lines]
| for (int i = 0; i < a.length; i++)
|   a[i].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
Jens Auer - 17 Feb 2006 09:10 GMT
> Mike Schilling schrieb:
>>> Mike Schilling schrieb:
[quoted text clipped - 38 lines]
> 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?
Roedy Green - 17 Feb 2006 10:00 GMT
On Fri, 17 Feb 2006 10:10:45 +0100, Jens Auer
<jens.auer-news@betaversion.net> 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();
 }
}

 
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Jens Auer - 17 Feb 2006 10:58 GMT
... 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.
Roedy Green - 18 Feb 2006 22:03 GMT
On Fri, 17 Feb 2006 11:58:14 +0100, Jens Auer
<jens.auer-news@betaversion.net> wrote, quoted or indirectly quoted
someone who said :

>     public static void f1(int[] a) {
>    for (int i=1000000; 0 != i--;)
>       for (int j=9; 0 <= j; --j)
>        a[j] = j;
>     }

You have to be very careful with this sort of benchmark. What you may
actually be measuring in the ability of the compiler to  optimise your
peculiar case test code away so it does nothing at all.  See
http://mindprod.com/jgloss/benchmark.html

You have to do real work the compiler can't slither out of, while at
the same time not adding so much overhead you disturb what you are
trying to measure.

What would really turn my crank in a 32-bit Periscope. In the old
16-bit days I could hit a hardware plunger that generated a
non-maskable interrupt, and then I could stop a program at that very
instant and see the assembler code it was running. I could single step
it if I wanted, or set breakpoints, all much like running Eclipse
debugger, but at the machine code level.

It was very useful for finding out what code was up to at times it was
irritating you.

Of course back then, except for the OS, I wrote every line of code
myself, so I knew my way around the assembler. Today, most of the code
is somebody else's and hence far more mysterious.

With such a tool, I could be sure HotSpot  had not pulled a sneaky
trick that would not apply in a real world situation.

I still keep and wear my Periscope tee shirt, torn though it is as a
sort of homage to a great departed tool.

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Mike Schilling - 17 Feb 2006 20:09 GMT
>> A "micro-optimization" is a performance optimization at a low level. For
>> example, the following construct:
[quoted text clipped - 19 lines]
> substraction. Can you explain why the first one is better to optimize, or
> just give me a web-page explaining this?

Do you see this much with upperbound being a constant or a simple variable?
If it's a more complex expression, you can see why, for example,

for( int i = list.size(); --i>=0; ) {
      // ...
   }

might be faster than

   for( int i = 0; i < list.size(); i++ ) {
      // ...
   }
tom fredriksen - 17 Feb 2006 09:14 GMT
> A "micro-optimization" is a performance optimization at a low level. For
> example, the following construct:
[quoted text clipped - 14 lines]
> 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:
[quoted text clipped - 16 lines]
> 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
Thomas Hawtin - 17 Feb 2006 10:20 GMT
> 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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Roedy Green - 17 Feb 2006 10:20 GMT
>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++)

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

tom fredriksen - 17 Feb 2006 11:15 GMT
>> 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
Roedy Green - 18 Feb 2006 22:06 GMT
>Fair enough, i thought I had written a statement like that a couple of
>days ago, but that was all in my mind.

Do you still write C, or dream in FORTRAN?

I have so many computer dreams about furiously coding all night and
wake up to discover it was all blithering nonsense.

I contemplate the possibility the Buddhists are right and eventually I
will awake from this reality to discover it was all blithering
nonsense too.  Global politics and the reaction of humanity to various
environmental crises make it feel like a ludicrous dream, just as my
dreams sometimes hint with their silliness they are not real.

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

tom fredriksen - 19 Feb 2006 17:24 GMT
>> Fair enough, i thought I had written a statement like that a couple of
>> days ago, but that was all in my mind.
[quoted text clipped - 9 lines]
> environmental crises make it feel like a ludicrous dream, just as my
> dreams sometimes hint with their silliness they are not real.

There is no need to that! Its an honest mistake. I am sure you have done
one or two in your lifetime as well.

/tom
Daniel Dyer - 17 Feb 2006 09:43 GMT
> 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  
[quoted text clipped - 9 lines]
> 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?
[quoted text clipped - 4 lines]
> 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.

Signature

Daniel Dyer
http://www.dandyer.co.uk

Timo Stamm - 17 Feb 2006 11:35 GMT
Daniel Dyer schrieb:
> 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.

Thanks Daniel, it makes a lot more sense 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.

Maybe it's time to update my bookshelf.

Timo
Daniel Dyer - 17 Feb 2006 19:22 GMT
> Maybe it's time to update my bookshelf.

It might be worth waiting for a couple of months, there is a second  
edition of Effective Java scheduled for around the time of this year's  
JavaOne.

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

Mike Schilling - 17 Feb 2006 20:10 GMT
>> Maybe it's time to update my bookshelf.
>
> It might be worth waiting for a couple of months, there is a second
> edition of Effective Java scheduled for around the time of this year's
> JavaOne.

Very cool.  Thanks for the heads up.
Mike Schilling - 17 Feb 2006 20:05 GMT
>> 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?

No, I'm quoting you.
tom fredriksen - 17 Feb 2006 09:21 GMT
> 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
Chris Uppal - 17 Feb 2006 14:16 GMT
> I get output like
>
>     Slow time is 6843 milliseconds.
>     Fast time is 63 milliseconds.

Just a couple of extra observations.

One is that (as Timo has mentioned) the -server optimisations (JDK 1.5.0) are
capable of almost eliminating the difference -- I find that quite surprising.
(I rejigged the code a little to ensure that the test wasn't being optimised
away).

Secondly I tried plugging ever larger[*] arrays into the code, but was unable
to find a point where the "slow" code caught up with the "fast" code (for
either -server or -client).  The relative difference declined dramatically, of
course, but never went away entirely.  Which suggests that the explicit bounds
test is completely compiled away and/or is being wrapped into the JVM's own
bounds checking (by the JITer or the chip).

([*] Up to 10M byte[] array)

   -- chris
Roedy Green - 18 Feb 2006 22:09 GMT
On Fri, 17 Feb 2006 14:16:08 -0000, "Chris Uppal"
<chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly
quoted someone who said :

>>     Slow time is 6843 milliseconds.
>>     Fast time is 63 milliseconds.
>
>Just a couple of extra observations.

Since Hotspot runs interpretively for a while, then mildly optimised,
the with server exhaustively optimised, it depend on when and how long
you time what sort of result you get.  

we are usually interested in the final state.  So let the benchmark
code "warm up" for a while before you start measuring it.  What a
"while" is, I don't know.  I suspect need to call the method the code
is in many times to kick in the optimisation.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Chris Uppal - 19 Feb 2006 16:23 GMT
> we are usually interested in the final state.  So let the benchmark
> code "warm up" for a while before you start measuring it.  What a
> "while" is, I don't know.  I suspect need to call the method the code
> is in many times to kick in the optimisation.

I put micro-benchmarks in a callable method, and then invoke  them in a
loop.  Often infinite.

   -- chris
Stefan Ram - 19 Feb 2006 16:27 GMT
>I put micro-benchmarks in a callable method, and then invoke
>them in a loop. Often infinite.

 For an attempt, albeit imperfect, to build a small framework
 for this purposes see »TimeThese1« in:

http://www.purl.org/stefan_ram/pub/timethese-in-java
Roedy Green - 17 Feb 2006 05:42 GMT
>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.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



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



©2009 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.