Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 430404

Summary: [1.8][inference][performance] Can we cut back on the bounds and constraints generated during inference ?
Product: [Eclipse Project] JDT Reporter: Stephan Herrmann <stephan.herrmann>
Component: CoreAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED WONTFIX QA Contact:
Severity: enhancement    
Priority: P3 CC: daniel.dietrich, jarthana, lukas.eder, register.eclipse, srikanth_sankaran
Version: 4.4   
Target Milestone: 4.8 M6   
Hardware: PC   
OS: Windows 7   
See Also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=543480
Whiteboard:
Attachments:
Description Flags
8000+ bound set elements none

Description Stephan Herrmann CLA 2014-03-14 12:01:09 EDT
With bug 430296 resolved for the immediate issue I still want to avoid creation of useless T#1 <: T#1 TypeBounds. Maybe some trivial constraints can be avoided, too.
Comment 1 Stephan Herrmann CLA 2014-04-15 06:40:09 EDT
Not necessary for 4.4, but some simple improvements may be applied time permitting.
Comment 2 Srikanth Sankaran CLA 2014-09-22 12:19:25 EDT
I'll work on this one for bug 442245.

Can we also get rid of the T#1 <: j.l.O bounds ?

What else ?
Comment 3 Stephan Herrmann CLA 2014-09-22 18:50:03 EDT
(In reply to Srikanth Sankaran from comment #2)
> I'll work on this one for bug 442245.
> 
> Can we also get rid of the T#1 <: j.l.O bounds ?

When you try that, please check with 18.1.3., which explicitly adds bounds
  αl <: Object
:)

We may have to ensure that each inference variable has at least one bound, not sure. 

> What else ?

We should make sure that adding a redundant type bound does not cause another round of incorporation.

Also note that comment 0 speaks of bounds *and* constraints.
Comment 4 Srikanth Sankaran CLA 2014-09-23 15:28:15 EDT
(In reply to Stephan Herrmann from comment #3)
> We may have to ensure that each inference variable has at least one bound,
> not sure. 

http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=550a751ce1bc873d333fa63fec3308d2d2a04ec5 has some improvements in this area.

Back to you Stephan for further work. Adjusted target to 4.5.
Comment 5 Srikanth Sankaran CLA 2014-09-25 09:07:31 EDT
We will use this bug for follow up performance improvements to https://bugs.eclipse.org/bugs/show_bug.cgi?id=442245

Test case is in GRT1_8: testBug442245

ATM, we take ~17 seconds to compile this.

In that test case, I am observing several hundreds of thousands constraints
being produced, reduced to bounds again in hundreds of thousands a huge 
majority of which are duplicates. We weed out duplicates by using a Set,
but ThreeSets.addBound and its descendants is where 2/3 of the time is now.

In https://bugs.eclipse.org/bugs/show_bug.cgi?id=442245, I have tuned the
performance of incorporate() itself, we now need to see what we can do to
cut the problem size.

I don't know how easy/feasible it would be to when we come across a bound
T#1 = T#2, to collapse both into a singularity (where they are not mapped
directly to type parameters.) and eliminate all traces of one of them.
Comment 6 Srikanth Sankaran CLA 2014-09-25 09:11:21 EDT
(In reply to Stephan Herrmann from comment #3)

> > Can we also get rid of the T#1 <: j.l.O bounds ?
> 
> When you try that, please check with 18.1.3., which explicitly adds bounds
>   αl <: Object
> :)

The only side effect to that pedanticism(?)/pedantry(?) appears to be the need
to insert a couple of three null guards.

See http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=550a751ce1bc873d333fa63fec3308d2d2a04ec5

> We should make sure that adding a redundant type bound does not cause
> another round of incorporation.

This is already done.
Comment 7 Srikanth Sankaran CLA 2014-09-25 10:20:15 EDT
Created attachment 247367 [details]
8000+ bound set elements

Are there any obvious categories begging for elimination ?
Comment 8 Srikanth Sankaran CLA 2014-09-25 19:00:11 EDT
(In reply to Srikanth Sankaran from comment #5)

> I don't know how easy/feasible it would be to when we come across a bound
> T#1 = T#2, to collapse both into a singularity (where they are not mapped
> directly to type parameters.) and eliminate all traces of one of them.

I have been context switching between several bugs and got the information tangled
up. This observation above is not pertinent to this bug.

The huge majority of bounds on this bug seem to be of the form:

Dependency R#1 :> test.Tuples.Tuple13<E1,T2#3,E3,T4#5,T5#6,E6,T7#8,T8#9,T9#10,T10#11,E11,E12,E13>

and its variants with different substitutions.
Comment 9 Stephan Herrmann CLA 2014-09-27 12:03:28 EDT
(In reply to Srikanth Sankaran from comment #6)
> (In reply to Stephan Herrmann from comment #3)
> 
> > > Can we also get rid of the T#1 <: j.l.O bounds ?
> > 
> > When you try that, please check with 18.1.3., which explicitly adds bounds
> >   αl <: Object
> > :)
> 
> The only side effect to that pedanticism(?)/pedantry(?) appears to be the
> need
> to insert a couple of three null guards.
> 
> See
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?id=550a751ce1bc873d333fa63fec3308d2d2a04ec5

note to self: check if in addition to the technical need for null checks Resolution also needs to reinsert the j.l.O bounds to produce valid results in all cases.
Comment 10 Stephan Herrmann CLA 2014-09-30 17:38:18 EDT
(In reply to Srikanth Sankaran from comment #6)
> (In reply to Stephan Herrmann from comment #3)
> 
> > > Can we also get rid of the T#1 <: j.l.O bounds ?
> > 
> > When you try that, please check with 18.1.3., which explicitly adds bounds
> >   αl <: Object
> > :)
> 
> The only side effect to that pedanticism(?)/pedantry(?) appears to be the
> need
> to insert a couple of three null guards.
> 
> See
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?id=550a751ce1bc873d333fa63fec3308d2d2a04ec5

I just happened to look at the loop at InferenceContext18.java:1015

This might cause havoc if we neither assign zsj.lowerBound nor call zsj.setUpperBounds().

The j.l.O bound would protect us against this situation. When we no longer add that bound we must ensure initialization of CaptureBinding18 assigns all necessary fields (firstBound, superclass, superInterfaces), even without setUpperBounds().
Comment 11 Srikanth Sankaran CLA 2014-11-08 14:10:46 EST
Taking a look at the bounds in the attachment, it looks to me that javac
is able to compile it super fast perhaps because they don't implement capture
bound incorporation (18.3.2) exactly as per the spec. Recall that they
create fresh inference variables only for wildcard type arguments in GA,
while we create them for every argument in GA leading to combinatorial
explosion.

Stephan, if you agree, I can prepare a patch that aligns with what javac
is doing. It should be a straightforward change that will eliminate
lots of noise bounds.
Comment 12 Srikanth Sankaran CLA 2014-11-09 04:19:14 EST
(In reply to Srikanth Sankaran from comment #11)

> I can prepare a patch that aligns with what javac
> is doing. It should be a straightforward change that will eliminate
> lots of noise bounds.

Nope, that is not it.
Comment 13 Srikanth Sankaran CLA 2014-11-09 07:27:10 EST
For the problem method (where we produce 8000+ bounds), we have an
instantiation for R1 very early on:

TypeBound  R#1 = test.Tuples.Tuple13<E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12,E13>

I wonder if that would be a legitimate reason to not continue to generate
dependencies of the form 

R#1 :> test.Tuples.Tuple13<E1,T2#3,E3,E4,E5,T6#7,E7,E8,T9#10,T10#11,T11#12,T12#13,E13>

Could the new bound serve some useful purpose ?

As an aside, the creation of so many bounds would directly result for
any verbatim implementation.

For faster solutions, we have to implement something different: 

18.3.1: 

α = U and S <: T imply ‹S[α:=U] <: T[α:=U]›

Instead of looking at pair wise, when we see a bound of the form:
S <: T, we could hypothetically look for every instantiation in the
bound set and mass incorporte them producing the minimal set of
bounds that would account for every permutation of instantantiations.

Not suggesting we do that, just jotting down my thoughts.
Comment 14 Stephan Herrmann CLA 2016-03-25 10:30:27 EDT
Too much on my plate for 4.6. Bulk deferral to 4.7
Comment 15 Stephan Herrmann CLA 2017-05-16 12:05:26 EDT
Ran out of time for 4.7. Bulk move to 4.8.
Comment 16 Stephan Herrmann CLA 2018-02-22 18:27:28 EST
No specific actions could be derived from this.
Comment 17 Jay Arthanareeswaran CLA 2018-03-08 23:54:59 EST
(In reply to Stephan Herrmann from comment #16)
> No specific actions could be derived from this.

Okay, let's close this.

Verified for 4.8 M6.