Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6533165
Votes 0
Synopsis Failure to optimize methods that unconditionally throw
Category hotspot:compiler2
Reported Against
Release Fixed
State 3-Accepted, request for enhancement
Priority: 3-Medium
Related Bugs 5103956
Submit Date 10-MAR-2007
Description
While trying to improve ArrayList performance for

5103956: (coll) Suggested improvement to speed up ArrayList<E> get and set calls

I encountered an anomaly in server compiler optimization.

Basically, since the performance of ArrayList.get() and set() is critical, 
we were willing to perform code micro-tweaks to make hotspot optimizers happy.

In particular, for error-handling, we had ArrayList.rangeCheck:

    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
    }

We refactored this to make the client compiler happier.

All of the possible refactorings gave equal performance under the server compiler,
except one.  Here are 3 refactorings:
 
       if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
 
    private String outOfBoundsMsg(int index) {
	return "Index: "+index+", Size: "+size;
    }
 

----------

          if (index >= size)
            throw outOfBoundsException(index);
 
    private IndexOutOfBoundsException outOfBoundsException(int index) {
	return new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
    }

----------

        if (index >= size)
            outOfBounds(index);
 
    private void outOfBounds(int index) {
	throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
    }

----------

The refactoring using outOfBounds is dramatically slower on my microbenchmark
than the others.  Using j2se/test/java/util/ArrayList/RangeCheckMicroBenchmark.java
I get, e.g. on solaris-amd64:

==> javac -Xlint:all RangeCheckMicroBenchmark.java
==> java -server -esa -ea RangeCheckMicroBenchmark
Method            Millis Ratio
get                   53 1.000
set                   48 0.907
get/set              188 3.487
add/remove at end   1360 25.210

vs.

==> javac -Xlint:all RangeCheckMicroBenchmark.java
==> java -server -esa -ea RangeCheckMicroBenchmark
Method            Millis Ratio
get                  180 1.000
set                  363 2.006
get/set              514 2.844
add/remove at end   1227 6.784

Notice the up-to-factor-of-8 decrease in performance.  A big penalty for
just moving some code around.

I'm not a hotspot engineer, but it looks like methods that unconditionally
throw confuse the optimizer.  But such methods are typical of attempts to
move error handling into a separate method, and is effective at speeding
up the client compiler, so users are likely to do this sort of thing.
The server compiler needs to examine outOfBounds and understand that it throws, 
but not inline it.  Maybe.
Posted Date : 2007-03-10 09:08:40.0
Work Around
N/A
Evaluation
N/A
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang