Node Count and JavaFX Performance
By Jim Connors 4 April 2009
In a recent blog entry entitled Best Practices for JavaFX Mobile Applications (Part 2), Michael Heinrichs espouses that keeping the scenegraph as small as possible helps JavaFX applications perform optimally. Regardless what version of JavaFX you're using, this is sage advice. Having spent some time trying to create components for a scoreboard-like application, I was concerned over the amount of CPU time being consumed by the clock component pictured directly below.
You can click on the preceding image to run this mini application via Java WebStart. By placing your mouse over any of the digits and typing in, via keyboard input, a valid number, you can set the clock. Clicking on the "START/STOP" text will toggle the clock on and off. Like many scoreboard clocks, when the time remaining is less than one minute, 10ths of seconds are displayed. It is during this phase, when digits are being updated every tenth of a second, that this application can be especially taxing. You can imagine how troublesome this clock might be if it were to be part of say a hockey scoreboard which could have an additional 4 penalty clocks ticking simultaneously.
The major factor affecting performance appears to be the sheer number of nodes in the scenegraph that require recalculation for every clock tick. For this first implementation, each of the five clock digits is comprised of 27 BulbNodes, (my naming) which are switched on or off depending upon what value needs to be displayed.
In an effort to see how decreasing the node count might effect performance, this second implementation of the clock component uses the same underlying framework, except that each digit is now composed of 7 LED SegmentNodes (my naming again) instead of 27 BulbNodes. You can run this version of the clock component by clicking on the image that follows.
For our final example, in order to truly minimize node count,
each digit is represented by a single ImageView node. When the value of
a digit changes, a new Image
is displayed. By caching all of the possible digit values
(blank, 0-9) you can very quickly switch images. No doubt,
prettier images can be created, but I think you get the
point. Click on the image that follows to try this version.
The Results
The slower the compute platform, the more pronounced the
differences in performance should be. Thinking along those
lines, a very modest 1.4 GHz Pentium M laptop was chosen as the
test environment to compare CPU utilization for these
applications. OpenSolaris provides an easy-to-use well-known
command-line tool called vmstat(1M),
which was chosen as the mechanism to analyze the individual
applications. In contrast, the Performance Tab which is part of
the Windows Task Manager, seemed to produce wild performance
variations.
For each run, the clocks were set to one minute, and run
until the time expired. The data shown below represents the
average CPU utilization, after startup, for each of the three
implementations. In particular we'll look at the following
fields returned by vmstat:
|
Number of
Nodes per Digit |
CPU
Utilization |
Implementation 1: BulbClockNode |
27 BulbNodes |
us: 22% sy: 2% id:
76% |
Implementation 2: LEDClockNode |
7 SegmentNodes |
us: 9% sy:
2% id: 89% |
Implementation 3: ImageClockNode |
1 ImageNode |
us: 3% sy:
2% id: 95% |
The JavaFX engineering team is well aware of this limitation, and
hopes to redesign the underlying scenegraph plumbing in the
future. Regardless, it's still a good idea to take into
consideration the size of your scenegraph.
JavaFX book status: Our upcoming book, JavaFX:
Developing Rich Internet Applications, is in copy
edit. Coming soon: Rough cuts of certain chapters will be
available on Safari.