Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 poor GUI performance compared to Java 6

In Java 6 below code is running as expected but in Java 8 it is taking much more time. The interesting part is that components use the same method setEnable() for enabling and disabling components, but the disabling call takes much longer than the enabling one, almost twice as much. Disabling in Java 8 is taking much longer than the one in Java 1.6. The question is why does this happen? Is this a performance problem of Java 8?

Here are the results for Java 6:

    Sun Microsystems Inc. 1.6.0_45
    Initializing GUI
    GUI initialized in 1105 ms
    Disabling
    Disabled in 687 ms
    Enabling
    Enabled in 375 ms

Here are the results for Java 8:

    Oracle Corporation 1.8.0_25
    Initializing GUI
    GUI initialized in 604 ms
    Disabling
    Disabled in 6341 ms
    Enabling
    Enabled in 370 ms

The code:

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class TestGUI extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;

    public TestGUI() {
        initGUI();
    }

    public void actionPerformed(ActionEvent e) {
        String text;
        if(e.getActionCommand().equals("Enable-ALL")){
            enableAll();
            text= "Disable-ALL";
        }
        else{
            disableAll();
            text= "Enable-ALL";
        }
        ((JButton)e.getSource()).setText(text);
        ((JButton)e.getSource()).setEnabled(true);

    }


    private  void initGUI() {
        long m = System.currentTimeMillis();
        System.out.println("Initializing GUI");
        setTitle(System.getProperty("java.vendor") + " " + System.getProperty("java.version"));
        setLayout(new FlowLayout());

        JButton b = new JButton("Disable-ALL ");
        b.addActionListener(this);
        add(b);

        for (int i = 1; i < 10001; i++) {
            b = new JButton("Button " + i);
            add(b);
        }
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600, 600);
        setVisible(true);
        m = System.currentTimeMillis() - m;
        System.out.println("GUI initialized in " + m + " ms");
    }

    private void disableAll() {
        long m = System.currentTimeMillis();
        System.out.println("Disabling");
        for (Component c : getContentPane().getComponents()) {
            c.setEnabled(false);
        }

        m = System.currentTimeMillis() - m;
        System.out.println("Disabled in " + m + " ms");
    }

    private void enableAll() {
        long m = System.currentTimeMillis();
        System.out.println("Enabling");
        for (Component c : getContentPane().getComponents()) {
            c.setEnabled(true);
            invalidate();
        }
        m = System.currentTimeMillis() - m;
        System.out.println("Enabled in " + m + " ms");
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                System.out.println(System.getProperty("java.vendor") + " "
                        + System.getProperty("java.version"));
                new TestGUI();
            }
        });
    }
}
like image 968
Mithat Bozkurt Avatar asked Jan 20 '15 13:01

Mithat Bozkurt


People also ask

Is Java GUI outdated?

Majority of existing GUI java codebases are Swing and likely will stay that way until the codebase rots and nobody maintains it anymore. Majority of new GUI java codebases are using JavaFX , which is the Swing replacement in Java8 and is part of the standard java library now.

Which is faster AWT or Swing?

swing component provide much flexible user interface because it follow model view controller(mvc). awt is not mvc based. swing works faster. awt does not work faster.

Is Java best for GUI?

The latest flagship of Oracle is JavaFX and is counted at top among the Best Java GUI frameworks. JavaFX is the latest toolkit of Java/Oracle replacing Swing to create rich desktop as well as web applications. Many new Java GUI programs are being developed using JavaFX.

Why is Java 6 being replaced by Java 8?

It is likely that those projects are implemented in Java 5 or 6 and are planned or already migrated to the latest version of Java. The most obvious reasons for moving from Java 6 to Java 8 are new language features and security improvements.

What are the advantages of Java 8 over Java 7?

Since multi-core processors are present everywhere today, one another important aspect of Java 8 is to simplify writing parallel (multi-threading) code easier and less error prone. It also brings functional programming possibilities to the core language. Moving from Java 7 or Java 6 to Java 8 could be not that straightforward.

Is it time to upgrade to Java 8?

Many of us are working on Java projects which have started some years ago. It is likely that those projects are implemented in Java 5 or 6 and are planned or already migrated to the latest version of Java. The most obvious reasons for moving from Java 6 to Java 8 are new language features and security improvements.

Is parallelity of Java 8 better than Java 5?

Therefore the parallelity is very good, better than 5 in both cases although some durations are not included in the sum which would make it even better. Garbage Collector Differences But obviously the Java 8 version is muchslower.


2 Answers

According to my profiler, the operation spends most of the time in the method Thread.holdsLock, which can be indeed a costly operation, which is called by Component.checkTreeLock which is called indirectly by Component.updateCursorImmediately.

Generally, you can avoid costly visual updates when updating multiple components by calling getContentPane().setVisible(false); right before the operation and getContentPane().setVisible(true); right afterwards, e.g.

private void disableAll() {
    long m = System.currentTimeMillis();
    System.out.println("Disabling");
    getContentPane().setVisible(false);
    for (Component c : getContentPane().getComponents()) {
        c.setEnabled(false);
    }
    getContentPane().setVisible(true);

    m = System.currentTimeMillis() - m;
    System.out.println("Disabled in " + m + " ms");
}

You will see, such problems will vanish, regardless of which kind of visual update causes the problem in detail.

So you don’t need to think about how to benchmark correctly here, not that it matters when the operation takes seconds, but I recommend learning the difference between System.currentTimeMillis() and System.nanoTime() as the latter is the right tool for measuring elapsed time.

like image 50
Holger Avatar answered Oct 16 '22 07:10

Holger


I haven't had a chance to understand exactly, but it seems like event handling might have changed in 8. Disabling the parent first speeds up the process:

getContentPane().setEnabled(false);
for (Component c : getContentPane().getComponents()) {
    c.setEnabled(false);
}
getContentPane().setEnabled(true);
like image 5
omerkudat Avatar answered Oct 16 '22 07:10

omerkudat