JDK-8103522 : Use modifiable BitSet in change listeners in CSS code
  • Type: Enhancement
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-05-13
  • Updated: 2015-06-16
  • Resolved: 2013-05-14
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.
JDK 8
8Fixed
Related Reports
Blocks :  
Duplicate :  
Description
...because it is much faster to just pass around the original BitSet and it looks like there is no way for application code to get to the data.

This diff gets us a 20% speedup on the TableViewTest benchmark on the Raspberry Pi using default parameters:

--- a/javafx-ui-common/src/com/sun/javafx/css/BitSet.java Mon May 06 15:11:35 2013 -0400
+++ b/javafx-ui-common/src/com/sun/javafx/css/BitSet.java Thu May 09 00:09:20 2013 +0300
@@ -549,7 +549,7 @@
         private final boolean removed;
 
         public Change(T element, boolean removed) {
- super(FXCollections.unmodifiableObservableSet(BitSet.this));
+ super(BitSet.this);
             this.element = element;
             this.removed = removed;
         }

If you run this on the desktop you can see with profiling tools that this saves a very large number of allocations of SetChangeAdapter objects. This accounts for the performance improvement on embedded platforms.

Is this change safe?
Comments
http://hg.openjdk.java.net/openjfx/8/controls/rt/rev/c0673a05cc60
14-05-2013

This was done because I want SetChangeListener#getSet to return an unmodifiable set. The real issue here is that there are Change instances being created when there are no listeners. The following change should ensure there are no instances of Change created unless there is a SetChangeListener added to the set. private void notifyObservers(T element, boolean removed) { - if (element != null) { + if (element != null && SetListenerHelper.hasListeners(listenerHelper)) { Change change = new Change(element, removed); SetListenerHelper.fireValueChangedEvent(listenerHelper, change); }
14-05-2013

I've just looked into this on my desktop machine by changing FXCollections.unmodifiableObservableSet to simply return the passed in set. Clearly not a long term solution, but interesting for testing. On my machine I gained roughly 1FPS (from 51 to 52). I'll try to take a look on a proper embedded device ASAP.
13-05-2013