JDK-7149409 : Extremely slow compilation time for visitor pattern code + generics
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_7
  • CPU: x86
  • Submitted: 2012-02-28
  • Updated: 2012-09-06
  • Resolved: 2012-02-28
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 7 x64

A DESCRIPTION OF THE PROBLEM :
The behaviour is the same as described in bugreport 6827648. Expect that i used JDK 1.7 Update 02 on Windows 7 x64.

  Description of bugreport 6827648:

FULL PRODUCT VERSION :
I have tried this using JDK 1.6 Update 13 on Windows x64, and the
problem persists.

A DESCRIPTION OF THE REQUEST :

Visitor pattern code which uses generics takes an unfeasibly long time (>30 seconds) to compile a single source file for a visitor.

The case causing difficulties appears to be:
(1) Genericised interface containing lots of methods all called "visit", all with similar but different signatures.
(2) Abstract generic class implementing (1) with all methods implemented
(3) Concrete non-generic class extending (2)

Compiling (3) takes an extremely long time. See the attached source code which generates Java code to be run through javac.


JUSTIFICATION :
The JTB (Java Tree Builder) extension to javacc uses the Visitor pattern extensively, and our solution uses over 40 different visitors. This increases the compile time of the whole project to about 25 minutes, whereas similar sized projects compile in under a minute.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Takes under a second to compile a single source file (extending AbstractClass<Object>) which contains no methods of its own.
ACTUAL -
Takes over 30 seconds to compile a single source file (extending AbstractClass<Object>) which contains no methods of its own.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;


public class CodeGenerator
{
	private final static String PATH = "D:\\tmp\\javacprob\\2";
	private final static int NUM_TYPES = 1000;
	
	public static void main(String[] args) throws FileNotFoundException
    {
		PrintStream interfacePs = new PrintStream(PATH + File.separator + "Interface.java");
		PrintStream abstractClassPs = new PrintStream(PATH + File.separator + "AbstractClass.java");
		PrintStream implementingClassPs = new PrintStream(PATH + File.separator + "ImplementingClass.java");
		interfacePs.println("public interface Interface<T> {");
		abstractClassPs.println("public abstract class AbstractClass<T> implements Interface<T> {");
		implementingClassPs.println("public class ImplementingClass extends AbstractClass<Object> {");
		
		for (int i=0; i<NUM_TYPES; i++)
		{
			String nodeName = "Node" + i;
			PrintStream nodePs = new PrintStream(PATH + File.separator + nodeName + ".java");
			nodePs.printf("public class %s { }\n", nodeName);
			nodePs.close();
			interfacePs.printf("void visit(%s node, T obj);%n", nodeName);
			abstractClassPs.printf("public void visit(%s node, T obj) { System.out.println(obj.toString()); }%n", nodeName);
		}
		interfacePs.println("}");
		abstractClassPs.println("}");
		implementingClassPs.println("}");
		interfacePs.close();
		abstractClassPs.close();
		implementingClassPs.close();
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The only workaround we have found is to use an alternative compiler.
Posted Date : 2009-04-08 07:20:33.0

REGRESSION.  Last worked in version 6u29


REPRODUCIBILITY :
This bug can be reproduced always.

Comments
EVALUATION This regression has been fixed in JDK 7u4. See 7142086.
28-02-2012