Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-9601

Parsing text into a class became much slower under Groovy 3.x

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0.4
    • 4.0.0-alpha-1, 3.0.5
    • Compiler
    • None
    • Openjdk 11

    Description

      Our Java application needs to execute dynamically generated Groovy code and we use the GroovyClassLoader to create a class from that generated code.

      When we tried to upgrade to Groovy 3.x we noticed a huge bump in the time it takes to create those dynamic classes (it became 10 times slower for some of them).

      Here is a very simple example of how we use the class loader:

      package lab;
      
      import groovy.lang.GroovyClassLoader;
      
      public class GroovySpeedLab {
      
          public static void main(String[] args) {
              StringBuilder buf = new StringBuilder();
              buf.append("package lab\r\n");
              buf.append("\r\n");
              buf.append("import groovy.transform.CompileStatic\r\n");
              buf.append("\r\n");
              buf.append("@CompileStatic\r\n");
              buf.append("class MyClass {\r\n");
              for (int i = 0; i < 1000; i++) {
                  buf.append("\r\n");
                  buf.append("    public void myMethod").append(i).append("() {\r\n");
                  buf.append("        println('method ").append(i).append(" invoked...')\r\n");
                  buf.append("    }\r\n");
              }
              buf.append("}\r\n");
      
              long start = System.currentTimeMillis();
              new GroovyClassLoader().parseClass(buf.toString());
              System.out.println("Done parsing in " + (System.currentTimeMillis() - start) + "ms");
          }
      }
      

      While this runs very quickly (because the methods are trivial), it it still consistently 50% slower with 3.x (but I am including this example mainly to show our use-case, not to focus on its speed difference).

      Our real application has much more complex classes (and many of them) and its initialization went from a couple of minutes to 10+ minutes.

      Is there another way to parse a given Groovy class without taking such a big performance hit with the new version of Groovy?

      Note that we also use many small Script objects created by calling GroovyShell.parse() and we noticed the same performance hit for those (I assume it uses the same mechanism under the hood).

       

       

       

      Attachments

        1. no_tuning.png
          57 kB
          Daniel Sun
        2. image-2020-06-25-17-42-31-315.png
          97 kB
          Daniel Sun
        3. groovy9601.svg
          1.67 MB
          Daniel Sun
        4. Groovy9601.groovy
          0.7 kB
          Daniel Sun
        5. Groovy9601_CLASSGEN.groovy
          0.8 kB
          Daniel Sun
        6. Groovy9601_CLASSGEN.groovy
          0.8 kB
          Daniel Sun
        7. Groovy9601_CLASSGEN_NO_STC.groovy
          0.8 kB
          Daniel Sun
        8. 50000.png
          52 kB
          Daniel Sun

        Activity

          People

            emilles Eric Milles
            fabian_depry@yahoo.com Fabian Depry
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 1h 20m
                1h 20m