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 :)