<div dir="ltr"><div><br></div><div>Hello,</div><div><br></div><div>I came across an interesting quirk of javac today. I was looking at unusually long compilation times of a bunch of test files. One of those files looks like this:</div><div><br></div><div>public class JavacBoom {<br>  public void ahem() {<br>         List<Map.Entry<String, String>> value =<br>        Arrays.asList(<br>            Map.entry("key", "value"),</div><div>            Map.entry("key", "value"),</div><div>            Map.entry("key", "value"),</div><div>            ...</div><div>            Map.entry("key", "value"),<br>        );<br>  }<br>}</div><div><br></div><div>Nothing special, except value is populated with many, many key-value pairs. I think type inference must have some kind of exponential algorithm in there because here is what it looks like when you increase the number of keys:</div><div><br></div><div>count of Map.entry(k,v), real time [seconds] javac JavacBoom<br>1, 0.4<br>10, 0.43<br>100, 1.08<br>200, 3.4<br>300, 10.8<br>400, 22.9<br>500, 50</div><div><br></div><div>So if you have 500 entries like the above, it'll take 50 seconds to compile a single ~10k bytes java source input. Here is a github gist with the source code containing 500 entries if you'd like to try locally:</div><div><a href="https://gist.github.com/dweiss/93caf579a89f3dbbfac5c292048e42ad">https://gist.github.com/dweiss/93caf579a89f3dbbfac5c292048e42ad</a></div><div><br></div><div>The compiler points here (roughly, single stack trace).</div><div><br></div><div>"main" #1 [1070081] prio=5 os_prio=0 cpu=1687.19ms elapsed=1.76s tid=0x00007de1b802a3f0 nid=1070081 runnable  [0x00007de1bcdfb000]<br>   java.lang.Thread.State: RUNNABLE<br>        at com.sun.tools.javac.code.Type.equalsIgnoreMetadata(jdk.compiler@23.0.1/Type.java:563)<br>      at com.sun.tools.javac.code.Types$Subst.visitTypeVar(jdk.compiler@23.0.1/Types.java:3355)<br>     at com.sun.tools.javac.code.Types$Subst.visitTypeVar(jdk.compiler@23.0.1/Types.java:3331)<br>     at com.sun.tools.javac.code.Type$TypeVar.accept(jdk.compiler@23.0.1/Type.java:1709)<br>   at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(jdk.compiler@23.0.1/Types.java:4920)<br>       at com.sun.tools.javac.code.Type.map(jdk.compiler@23.0.1/Type.java:319)<br>       at com.sun.tools.javac.code.Types.subst(jdk.compiler@23.0.1/Types.java:3328)<br>  at com.sun.tools.javac.comp.InferenceContext.asUndetVar(jdk.compiler@23.0.1/InferenceContext.java:206)<br>        at com.sun.tools.javac.comp.Infer$GraphSolver$InferenceGraph.initNodes(jdk.compiler@23.0.1/Infer.java:1907)<br>   at com.sun.tools.javac.comp.Infer$GraphSolver$InferenceGraph.<init>(jdk.compiler@23.0.1/Infer.java:1852)<br>        at com.sun.tools.javac.comp.Infer$GraphSolver.solve(jdk.compiler@23.0.1/Infer.java:1654)<br>      at com.sun.tools.javac.comp.InferenceContext.solve(jdk.compiler@23.0.1/InferenceContext.java:487)<br>     at com.sun.tools.javac.comp.InferenceContext.solve(jdk.compiler@23.0.1/InferenceContext.java:494)<br>     at com.sun.tools.javac.comp.Infer.instantiateMethod(jdk.compiler@23.0.1/Infer.java:211)<br>       at com.sun.tools.javac.comp.Resolve.rawInstantiate(jdk.compiler@23.0.1/Resolve.java:619)<br>      at com.sun.tools.javac.comp.Resolve.selectBest(jdk.compiler@23.0.1/Resolve.java:1588)<br> at com.sun.tools.javac.comp.Resolve.findMethodInScope(jdk.compiler@23.0.1/Resolve.java:1794)<br>  at com.sun.tools.javac.comp.Resolve.findMethod(jdk.compiler@23.0.1/Resolve.java:1865)<br> at com.sun.tools.javac.comp.Resolve.findMethod(jdk.compiler@23.0.1/Resolve.java:1838)<br> at com.sun.tools.javac.comp.Resolve$12.doLookup(jdk.compiler@23.0.1/Resolve.java:2770)<br>        at com.sun.tools.javac.comp.Resolve$BasicLookupHelper.lookup(jdk.compiler@23.0.1/Resolve.java:3485)<br>   at com.sun.tools.javac.comp.Resolve.lookupMethod(jdk.compiler@23.0.1/Resolve.java:3749)<br>       at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(jdk.compiler@23.0.1/Resolve.java:2767)<br>     at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(jdk.compiler@23.0.1/Resolve.java:2761)<br>     at com.sun.tools.javac.comp.Attr.selectSym(jdk.compiler@23.0.1/Attr.java:4546)<br>        at com.sun.tools.javac.comp.Attr.visitSelect(jdk.compiler@23.0.1/Attr.java:4433)<br>      at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(jdk.compiler@23.0.1/JCTree.java:2570)<br> at com.sun.tools.javac.comp.Attr.attribTree(jdk.compiler@23.0.1/Attr.java:674)<br>        at com.sun.tools.javac.comp.Attr.visitApply(jdk.compiler@23.0.1/Attr.java:2641)<br>       at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(jdk.compiler@23.0.1/JCTree.java:1857)<br>    at com.sun.tools.javac.comp.Attr.attribTree(jdk.compiler@23.0.1/Attr.java:674)<br>        at com.sun.tools.javac.comp.Attr.attribExpr(jdk.compiler@23.0.1/Attr.java:720)<br>        at com.sun.tools.javac.comp.Attr.visitVarDef(jdk.compiler@23.0.1/Attr.java:1318)<br></div><div><br></div><div>I don't have the karma to submit jira issues, but I think this can be considered a showstopper?</div><div><br></div><div>Dawid</div></div>