Three days ago, I posted a design pattern for menubars. While the article was mainly about code clarity and the clumsiness of inner classes, it also contained some remarks concerning performance and naturally this puts me in a put up or shut up situation, even though a performance discussion was not really my intention.
So, lets see what the numbers look like. For this, I will write the same GUI application twice. Once with and once without using inner classes to forward events to actionhandler methods. The application itself will consist of one JTextArea (just to put something in the contentpane) and a menubar holding six menus, containing ten menuitems each. This amount was chosen as a rough ballpark figure of what a "typical" program might have. The skeleton of both testing classes will look like this:
import javax.swing.*;
import java.awt.event.*;
public class Skeleton extends JMenuBar {
/**
* One handler per menuitem.
*/
private void handleItem_X_Y() {}
//..
public static void main(String[] args) {
long start = System.currentTimeMillis();
JFrame frame = new JFrame("Skeleton");
frame.setJMenuBar(new Skeleton());
frame.getContentPane().add(new JTextArea(10,40));
frame.pack();
frame.setVisible(true);
System.err.println("Setuptime (Skelleton): "+(System.currentTimeMillis()-start)
}
}
The actual code can be found attached to this article. The test itself will be about comparing startup time and compiled codesize of both classes. Test environment:
- Ubuntu Linux 8.04 (Hardy Heron) - 32 bit version
- AMD Athlon(tm) 64 Processor 3000+
- 512 MB RAM
- JDK: java-6-sun-1.6.0.06 (shipped with Ubuntu)
To compile and run the following commands were used:
javac Mybar.java
jar -cf MyBar.jar MyBar.class
java -cp MyBar.jar MyBarjavac MyInnerBar.java
jar -cf MyInnerBar.jar MyInnerBar*
java -cp MyInnerBar.jar MyInnerBarThe test result showed a compressed size of 4.363 bytes for MyBar.jar and 32.796 bytes for MyInnerBar.jar. The initialization took 722 ms for MyBar vs. 760 ms for MyInnerBar (average of 10 runs each). The runtime of MyBar.actionPerfomed(ActionEvent) was found to be always below one millisecond. A comparison of "==" vs. equals() was omitted.
The conclusion to draw from this test is, that the use of anonymous, inner classes to forward events does not only decrease sourcecode clarity and increase sourcecode bloat. There is also a penalty in compiled code size and execution speed. The impact is likely not big enough to seriously affect Desktop applications, but might become an issue in tight environments like Applets or mobile applications. In any way there is nothing to gain from using inner classes in event listeners as shown in the original article.
| Attachment | Size |
|---|---|
| testcode_performance.zip | 3.96 KB |
Similar posts
- A design pattern for Menubars
- Saving preferences for JToolBar location and window geometry
- Java and directory trees - The joy of implementing a simple filemanager
- Writing modular Java applications (a suggestion for a simple, but versatile plugin architecture)
- Parsing email addresses in Java (without having the JavaMail API available)
