JDK-8212124 : Reduced performance of java.awt.Graphics2D.drawPolyline
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 9,11,12
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2018-10-09
  • Updated: 2018-12-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Duplicate :  
Relates :  
Description
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



Comments
It is not clear that we can "directly" fix this, we may just be able to make the specific code path marginally better, but cannot do anything to equal the untransformed performance.
09-12-2018

This isn't really a slow down in polyline. It is a different code path being taken due to running on a hi-dpi device. Also the large (64K) number of points exaggerates the slowness of this code path. See the long thread here : http://mail.openjdk.java.net/pipermail/2d-dev/2018-October/009523.html
12-10-2018

Performance of java.awt.Graphics2D.drawPolyline in JDK 11 is very slow when compared to JDK 8u. Checked this for reported version and could confirm this as a performance regression in JDK 9 and above. Results: ======== JDK 8u181: 0.041s JDK 9: 84.787s JDK 10.0.2: 80.137s JDK 11: 89.39s JDK 12: 83.304s To verify, run the attached test case with respective JDK version. This seems a performance regression in JDK 9 and onwards.
12-10-2018