Startup time for a large Swing application using Nimbus is unacceptably long compared to Metal. I performed some basic profiling and found that the majority of the CPU time is spent initializing NimbusStyle. This is not surprising since at least one for each component it must run through this initialization code. The code was originally written to be easy to read and correct -- but it is in a performance critical loop and now needs to be optimized.
In particular, a large amount of time was spent creating HashMaps and populating them. This could be optimized by using a static HashMap (since all this code should only ever be run on the EDT). Further, each time a style is initialized it will parse through all the entries in the UIDefaults class looking for entries that pertain to it. In this case, we can precompile the data such that it is retrieved from a datastructure and parsed only when UIDefaults changes, as opposed to parsing on each loop.
Also, we use String.split(","), for splitting of the states, which invokes regular expressions and is slowing things down as opposed to handling this splitting manually. Also, we use the enhanced for loop in these methods which creates a bunch of unnecessary iterators.
Nearly every method in the profiler that appeared slow eventually led to the two init methods in NimbusStyle. Improving those methods should lead to a much faster startup time.