Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6827648

Extremely slow compilation time for visitor pattern code + generics

    Details

    • Subcomponent:
    • Resolved In Build:
      b70
    • CPU:
      x86
    • OS:
      windows_xp
    • Verification:
      Not verified

      Description

      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.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                mcimadamore Maurizio Cimadamore
                Reporter:
                ndcosta Nelson Dcosta
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: