RFR: JDK-8322964 Optimize performance of CSS selector matching [v2]
John Hendrikx
jhendrikx at openjdk.org
Sun Jan 14 05:03:31 UTC 2024
On Sun, 14 Jan 2024 04:20:56 GMT, Michael Strauß <mstrauss at openjdk.org> wrote:
>> This is possible, although `List#get` would not perform too well when it is implemented for `FixedCapacitySet.OpenAddressed` as the array used as hash table in this class can have gaps (so we'd need to iterate to find the index).
>>
>> However, I am very sure this method is not used anywhere (not even in 3rd party code as it requires casting to access), and I wouldn't encourage its use, so I'd be more inclined to remove it completely.
>
> If this method is not used anywhere, why do we need to expose `getStyleClassNames()` as new API to replace this one? I'm a bit puzzled by that, especially since you're saying that the API shouldn't be used. Why create something that shouldn't be used?
>
> I'd rather just document that you shouldn't expect great performance from this method, and be done with it. Changing API in a performance optimization PR seems out of scope.
You were talking about `List<String> getStyleClasses()`. This is not used by FX, and unlikely to be used anywhere by 3rd parties (see reasoning in other comment).
Then there is a 2nd method: `Set<StyleClass> getStyleClassSet()`. This is/was called by `SelectorPartitioning`, an internal FX class. However, this method makes use of the `StyleClass` wrapper that is hurting performance.
To ensure `SelectorPartitioning` has a fast way to access the styles, I needed a new method: `Set<String> getStyleClassNames`. As it is called from outside the `javafx.css` package, it has to be `public`.
**Now perhaps you were eluding to something else:**
Would `SelectorPartitioning` mind if the styles were provided as `List` or `Collection`? Looking at that code, I think it doesn't really care. It just uses the set as a key, and calls `containsAll` on it. So perhaps we don't need to deprecate `List<String> getStyleClasses()` then, and we don't need a new API. Instead I'll have `SelectorPartitioning` be happy with a `Collection` so I also don't have to make make a set implement a `List` (which you can't do without violating the contract of either `List` or `Set` as `hashCode` is defined differently).
Edit: it would still need to be a `List` as I can't return a `Set<String>` from a method that returns `List<String>`... that means either change that method to return `Collection`, so still need an API change, or store everything as `List`...
The only thing that may land us into trouble here (reusing `List<String> getStyleClasses()`) is that there may be an expectation that it still contains duplicates, and retains the original order with which `SimpleSelector` was created. This is already not the case (as it is based on the old `BitSet` that was created) -- it is deduplicated, and its order is changed (whether that was the intention is unclear, but that's what it does right now). Then again, the method is currently not in use...
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/1316#discussion_r1451656563
More information about the openjfx-dev
mailing list