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

Reduced performance of java.awt.Graphics2D.drawPolyline

XMLWordPrintable

    • 2d
    • 9
    • x86_64
    • windows_10

      ADDITIONAL SYSTEM INFORMATION :
      Java 11:
      openjdk version "11" 2018-09-25
      OpenJDK Runtime Environment 18.9 (build 11+28)
      OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

      Java 8:
      openjdk version "1.8.0-adoptopenjdk"
      OpenJDK Runtime Environment (build 1.8.0-adoptopenjdk-_2018_05_19_00_59-b00)
      OpenJDK 64-Bit Server VM (build 25.71-b00, mixed mode)

      System:
      Windows 10 64-bit Pro 1803, build 17134.320, Intel core i7
      Intel graphics, display scaling 125% (default)


      A DESCRIPTION OF THE PROBLEM :
      drawPolyline seems to be a lot slower on Java 11, compared to Java 8, running exactly the same JAR. I saw this on a graphing application with very detailed graphs. I have also reproduced this with test code. On the test code, the paint routine executes in < 100ms on Java 8 but takes over 20 seconds on Java 11.

      REGRESSION : Last worked in version 8u181

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a Java program with a JFrame containing a custom subclass of JComponent
      2. Implement the component's paintComponent method to include
              graphics.drawPolyline(xs, ys, xs.length);
      where xs and ys are two pre-initialised, large int[] arrays
      3. Build and run using JDK8 and JDK11
      4. Resize the frame to force a repaint
      (I have a complete Netbeans project to attach)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Both should work about the same (JDK11 window is bigger because of HiDPI scaling)
      ACTUAL -
      JDK11 is much slower, many seconds elapse between resizing the window and the display refreshing

      ---------- BEGIN SOURCE ----------
      === canvas.java ===
      package polylinetest;

      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.util.Random;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import javax.swing.JComponent;

      public class Canvas extends JComponent {

          public static int SIZEGRADE = 16;

          public Canvas() {
              Random rnd = new Random();
              int len = 1 << SIZEGRADE;
              xs = new int[len];
              ys = new int[len];
              for (int i = 0; i < len; ++i) {
                  xs[i] = rnd.nextInt(640);
                  ys[i] = rnd.nextInt(480);
              }
          }

          @Override
          protected void paintComponent(Graphics g) {
              super.paintComponent(g);
              Graphics2D graphics = (Graphics2D) g;
              long starttime = System.nanoTime();
              graphics.drawPolyline(xs, ys, xs.length);
              long endtime = System.nanoTime();
              Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Paint Time: {0}s", (double) (endtime - starttime) / 1.0e9);
          }
          private final int[] xs;
          private final int[] ys;
      }
      ======

      === PolylineTest.java ===
      package polylinetest;

      import javax.swing.JFrame;

      public class PolylineTest {
          public static void main(String[] args) {
              JFrame frame = new JFrame("polyline test");
              frame.setSize(640, 480);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.getContentPane().add(new Canvas());
              javax.swing.SwingUtilities.invokeLater(() -> frame.setVisible(true));
          }
          
      }
      ======
      ---------- END SOURCE ----------

      FREQUENCY : always


            prr Philip Race
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: