JDK-4911244 : Reduce init time for UI defaults
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2003-08-22
  • Updated: 2013-11-01
  • Resolved: 2003-11-03
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
5.0 b28Fixed
Related Reports
Relates :  
Relates :  
Description
In a recent startup performance analysis, the initialization of the
UI defaults for Swing took up a large percentage (about 10%) of the overall
time to start a simple Swing app.  Much of the work boiled down to simple
(but very plentiful) method calls such as:
- StringBuffer.append (which can end up calling StringBuffer.expandCapacity, which can be quite expensive; there was one call in the test app that took
nearly 25 ms)
- Hashtable.put: there are a LOT of these calls made during initComponentDefaults
- ResourceBundle.findBundle: there are a lot of these relatively expensive calls in UIDefaults.getResourceCache
- Hash.[put|get]: LOTS of calls to these methods are made in some of the methods called from UIDefaults.getResourceCache

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger tiger-beta FIXED IN: tiger-beta INTEGRATED IN: tiger-b28 tiger-beta
14-06-2004

EVALUATION I believe there are a handful of changes to be done here that will improve startup. Whether or not they make a difference will have to be investigated. ###@###.### 2003-09-24 I'm assuming by time spent creating UIDefaults Chet actually means time spent initializing the UIManager and creating the first UI as this is where the bulk of the time for Swing in the startup test is going. On my linux box this comes across as 9% of total time, and 8% of total time on my sparc box. As to the specifics Chet comments on: . StringBuffer usage from initClassDefaults. These have been nuked. For ease of changing packages we had code like: String basicPackageName = "javax.swing.plaf.basic."; ... "ButtonUI", basicPackageName + "BasicButtonUI" which ends up creating a StringBuffer. This is trivially converted to: ... "ButtonUI", "javax.swing.plaf.basic.BasicButtonUI" . Hashtable.put: Swing is very much property driven. We populate a big Hashtable (UIDefaults) and our behavior is driven from this. We're locked into using Hashtable because of public API and there isn't much we can do about this. . ResourceBundle.findBundle: Swing displays a bunch of localized strings that are accessed from the defaults table. If we can't find a match for a particular key we search in the ResourceBundle for the value. As ResourceBundle doesn't have a cheap way of determining if a key is present (refer to 4494785 and 4286358) we end up creating our own Hashtable will all the values from the ResourceBundles. Swing's API for adding resourcebundles is public, so that we are currently forced to load the resource bundles at this point. . HashMap.put/get: this is because we are forced to cache the values in the ResourceBundle. If 494785 and/or 4286358 were fixed we could avoid caching the ResourceBundles. Slogging through qtrace there are a number of various changes that can be done to improve the startup time of the Swing portion: . Change BasicLookAndFeel/MetalLookAndFeel/WindowsLookAndFeel to avoid indirect use of StringBuffer by way of adding Strings with +. . Nuke SwingUtilities.doPriviledged. There is really no reason for this and it ends up creating an extra PriviledgedAction to wrap the passed in Runnable. . RepaintManager had it's own Runnable for looking up a system property, it should use GetPropertyAction. . Make UIManager.LAFState lazily create its SwingPropertyChangeSupport. Rationale being it's very rarely used. . UIManager.makeSwingProperties was doing a doPriviledged to get a system property, but its called from within a doPriviledged. . UIMananager.setLookAndFeel now special cases MetalLookAndFeel to avoid the Class.forName and newInstance calls. . Removed calls to Compiler.disable and Compiler.enable in UIManager. Tom said they don't do anything with hotspot. . Changed UIDefaults to pass in a largish value to it's superclass constructor (Hashtable) as the table usually ends up being pretty big. . Changed MetalLookAndFeel to cache values it's going to put in the defaults table multiple times to avoid repeated lookups. . Created sun.swing.SwingLazyValue which is a duplicate of UIDefaults.ProxyLazyValue, but doesn't do a doPriviledged or cache the AccessControlContext at the time of creation. . OceanTheme now calls putDefaults instead of put to avoid repeated attempts to fire a PropertyChangeEvent. It also caches some values that are set multiple times. . BasicLookAndFeel had it's own copy of SwingUtilities.doPriviledged. This has been nuked. . BasicLookAndFeel now only installs the listener for popups if a popup has been created. This requires an API change to add the constructor. ###@###.### 2003-09-26 One other change that was done: . UIManager.initializeSystemDefaults no longer sets the system defaults UITable on the MultiUIDefaults. This is no longer necessary as the mechanism for getting the FocusManager class name changed in 1.4. Here are the numbers on my Windows box: Real time Swing time before 1.23 130 after 1.23 110 And on my sparc box: Real Swing before 1.89 129 after 1.86 110 The real time is the time displayed from time -p and the Swing time is the time it takes JPanel to create a UI, or the time for initializing Swing and creating the first widget. What this shows is that while these changes helped reduce the Swing portion by ~15% this doesn't make a noticable difference in the overall startup:( ###@###.### 2003-09-29
29-09-2003