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

getBounds() method of TextLayout is very slow with HarfBuzz font engine (Windows)

    Details

    • Subcomponent:
    • Introduced In Version:
      9
    • CPU:
      x86_64
    • OS:
      windows_10

      Description

      ADDITIONAL SYSTEM INFORMATION :
      Window 10, Java 10 and onwards

      A DESCRIPTION OF THE PROBLEM :
      Performance degredation of getBounds() method of java.awt.font.TextLayout
      We are observing performance degradation by many fold when using HarfBuz as a font engine when data is large.
      In our specific use case we are using poi library that using making use of TextLayout to get the width of every column. We are wiriting 20000 rows to spreadsheet :
      With ICU as font engine : 2.3 to 3 seconnds
      With HarfBuzz as font engine : 50 to 80 seconnds

      REGRESSION : Last worked in version 8u212

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      call getBounds() method of TextLayout for large data set i.e. for large number of TextLayouts.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Total time consumed in java 8 and java 10 & above should be nearly same.
      Expected Time consumed arround 1.5 seconds
      ACTUAL -
      Total time consumed in java 10 & above is much much high than time consumed in java 8.
      Actual Time consumed more than 40 seconds

      ---------- BEGIN SOURCE ----------
      import java.awt.font.FontRenderContext;
      import java.awt.font.TextLayout;
      import java.awt.geom.AffineTransform;
      import java.awt.geom.Rectangle2D;
      import java.text.AttributedString;

      public class TextlayoutPerf {

          private static final FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);

          public static void main(String[] args){

              long start = System.currentTimeMillis();
              String text = "test test test stet test test test test test";
              //Equivalent to 20000 rows and 2 column
              for (int j = 0; j < 3 ; j++) {
                  for (int i = 0; i < 20000; i++) {
                      getCellWidth(15, 0, 25, new AttributedString(text));
                  }
              }

              System.out.print(System.currentTimeMillis() - start);

          }

          private static double getCellWidth(int defaultCharWidth, int colspan, double minWidth, AttributedString str) {
              TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
              final Rectangle2D bounds;
              long start1 = System.currentTimeMillis();
              bounds = layout.getBounds();

              // frameWidth accounts for leading spaces which is excluded from bounds.getWidth()
              final double frameWidth = bounds.getX() + bounds.getWidth();
              return frameWidth;
          }

      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      No workarround in java 10

      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                prr Philip Race
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated: