5

I am trying to optimize the performance of an application by switching from Java2D to OpenGL (LWJGL). I wrote myself some benchmarks to see the performance difference between those two and was happy with the result in the beginning. However when I ran my benchmarks on a different machine, the outcome was quite shocking for me.

This is the benchmark in question:

public static void main(String[] args) throws InterruptedException {
    //create window
    JFrame frame = new JFrame();
    frame.setSize(1000, 1000);
    frame.setLocation(0, 0);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    //add drawable component
    frame.add(new JComponent() {
        protected void paintComponent(Graphics graphics) {
            Graphics2D g = (Graphics2D) graphics;
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g.setFont(g.getFont().deriveFont(24f));
            
            long start = System.nanoTime();
            for(int i=0;i<500;i++){
                g.drawString("This is a test string - This is a test string - This is a test string",10, 20+i*2);
            }
            long end = System.nanoTime();
            long nsDuration = (end-start);
            
            System.out.println("DrawString takes: "+(nsDuration/1_000_000)+" ms");
    }});
    frame.setVisible(true);
    
    boolean t=true;
    while(t){
        frame.repaint();
        Thread.sleep(1000);
    }
}

I developed it on my desktop computer (CPU:i3-3220, GPU:HD7850) where i get outputs like this:

DrawString takes: 281 ms

DrawString takes: 299 ms

DrawString takes: 282 ms

The OpenGL version of the benchmark gave me times around ~4ms, so ~75x better performance, which seems good.

When I ran the benchmark on my 10 year old, much weaker Laptop (CPU: P8600, GPU:Intel GMA 4500MHD), however the results for the OpenGL version as well as the Java2D version were around ~20ms. So two things to note:

  • Java2D on my old laptop ran as fast as my OpenGL implementation
  • My 10 year old laptop outperformed my desktop sporting a dedicated GPU by more than an order of magnitude!

I was and still am at a loss for words and was thinking of potential causes. JRE versions on both machines are close (1.8.1xx) and they run the same OS (Windows 8.1). I also made absolutely sure, that Java isn't using hardware acceleration by passing "-Dsun.java2d.opengl=false" to the JVM without any effect.

So I thought that maybe something is up with the fact that the Laptop's iGPU somehow benefits from how it is connected memory wise. I configured my desktop to run on it's iGPU (HD Graphics 2500) as well, in order to test my hypothesis. The result was that the same benchmark executed in ~7ms on my desktop with the iGPU activated.

While I found a reason to why my laptop was faster than my desktop, I still don't understand it...

  • Can someone explain to me, why Java2D is so much faster on an iGPU in this case?
  • Shouldn't transfering that ~4MB worth of UI (in terms of raw pixel data) to a dedicated GPU be faster than 290ms?
  • Is this a (performance-)bug in Java2D?

EDIT: I was thinking that maybe the iGPU hypothesis is still wrong and it's an issue with AMD/ATI... so if anyone runs the benchmarks with different results or on a NVIDIA GPU, shared results would be appreciated :)

Community
  • 1
  • 1
Wolf
  • 892
  • 2
  • 8
  • 22
  • 1
    your microbenchmark will be susceptible to many factors which you don't control for. Try using Java Microbenchmark Harness (http://www.baeldung.com/java-microbenchmark-harness) – diginoise Mar 16 '18 at 16:00
  • Will this link be any help to answer to your question? http://www.oracle.com/technetwork/java/perf-graphics-135933.html – Vikram Palakurthi Mar 16 '18 at 16:09
  • @diginoise Thanks for the pointer, haven't heard of JMH! However, I am ignoring the first couple of results anyways, running many iterations (which should normalize the measured time) and are only interested in big performance discrepancies (if the results were 10% difference, i would agree, that I should revise the robustness of the benchmark... but we are talking about 1000% and more). – Wolf Mar 16 '18 at 16:14
  • @VikramPalakurthi: Do you mean any paragraph specifically? I don't see how that 15 year old article would explain anything of what i experience here... – Wolf Mar 16 '18 at 16:14
  • @Wolf this post https://stackoverflow.com/questions/35641229/java2d-opengl-graphics-acceleration-not-working suggests that the switch to enable OpoenGL is case sensitive `True`. The value to disable it is most likely `False`, so it's possible that you are not being accelerated when you think you are O_o – diginoise Mar 16 '18 at 16:29
  • Few more details about getting some debug output out of of OpenGL: https://docs.oracle.com/javase/9/troubleshoot/java-2d-pipeline-rendering-and-properties.htm#JSTGD441 – diginoise Mar 16 '18 at 16:36
  • @diginoise: As per your last link the case should only affect the debug output, not the functionality, from what I understand. I tried to run the benchmark again with "False" anyways without any effect. Side note: When I tried enabling the hardware acceleration some days/weeks ago, my Java2D program would regularily crash. When googleing i found several accounts of people saying the acceleration is rather unstable. – Wolf Mar 16 '18 at 16:39
  • Fair point about debug vs.enable/disable. Perhaps logs show something which would explain the result... All I keep finding is to keep the graphic drivers up to date. – diginoise Mar 16 '18 at 16:44

0 Answers0