JDK-8015668 : overload resolution: performance regression in JDK 7
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7u40
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-05-30
  • Updated: 2013-11-05
  • Resolved: 2013-06-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7u40 b32Fixed
See attached sources.zip containing ArrayUtil.java & MethodHandle.java, taken from Groovy sourcecode.
They exhibit a case with which javac performs very badly.

 javac ArrayUtil.java #Not too bad
 javac MethodHandle.java # But this takes many minutes

Note that MethodHandle references ArrayUtil, and this is auto-generated code.

ECJ compiles this source code in ~4 seconds.

This problem is present in JDK8 and JDK7.

     - The performance problem stems from com.sun.tools.javac.comp.Resolve.InapplicableSymbolsError.Candidate#equals. This is used during method resolution, and is performed O(n^2) times for 'n' same-name methods. It references rather expensive methods that iterate over and potentially copy (eg for erasure) both argument lists, which can be up to 255 elements in this case.
     - MethodHandle references a method from ArrayUtil that has 255 candidates; this is many orders of magnitude slower than it should be.

I have attached a patch that does a hackish fix, by providing a fast route for when method is obviously not a sub-signature of another.
The patch is mainly there as a proof-of-concept (its rather slapped on), hopefully someone knows a better way to fix these corner cases?

I am rather dubious about argument lists pervasively being treated as singly-linked lists. It makes certain operations quite costly, even changing the complexity of them unfavourably.
This bug was only present in 7, 8 already have this implemented in a similar way.

Verified 7u40 b32

We are waiting for the repo for 7.40 to be available in order to push this patch.

SQE is OK with this fix

I will approve this - provided that 1) there's SQE-OK and 2) the release team reviews and doesn't have any concerns. Please get SQE to review and mark with SQE-OK if they agree to this fix

7u40-critical-request. Javac has a very bad performance for this corner case. The patch for this bug is under review and drops the compilation time from 5 min to 5 secs aprox.

I believe the solution for this is to maintain a fixed-size heap of candidate; this stuff is mostly there for generating better overload diagnostics; but in the case you have 255 candidates, I doubt you want to see them all.