On Sat, 9 Mar 2024 06:08:34 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:
>> modules/javafx.graphics/src/main/java/com/sun/javafx/css/FixedCapacitySet.java >> line 96: >> >>> 94: : maximumCapacity == 2 ? new Duo<>() >>> 95: : maximumCapacity < 10 ? new Hashless<>(maximumCapacity) >>> // will reject negative values >>> 96: : new >>> OpenAddressed<>(maximumCapacity); >> >> I wonder if standard HashSet should be used instead of OpenAddressed one, or >> should there be another threshold which results in a HashSet, to support >> large sets? >> >> Or we can reasonably guarantee that these sets are always small? > > It's possible to use the standard `HashSet` as a final fallback (or even to > replace `OpenAddressed`), although it would need to be wrapped so support the > `freeze` method (or we need to implement this differently). > > There are a few reasons however not to do so: > - `HashSet` doesn't support `freeze` so we'd need to copy it after it is > created; we can't use `Set.of` as this would also require making a copy of > the entries first (the entries are added one by one because empty values are > filtered) -- the solution in this PR carefully avoids all unnecessary copying > and allocations to achieve the better performance > - The sets are indeed in almost all cases very small (hence the optimizations > for small sets) -- they contain style classes that apply to a single node or > a single selector. Nodes with many style classes applied to them (ie. 10 or > more) I think rarely occurs in practice. Same goes for selectors; you'd have > to have something like `a > b c d e f g h i > j` as selector -- remember that > this doesn't apply to something like `a, b, c, d, e, f, g, h, i, j`, as they > are actually 10 different selectors with 1 style each. > - `HashSet` is less memory efficient (between 21.5 to 26.7 bytes per entry > with the load factor varying between 0.75 and 0.75 * 0.5; `16 + 4 / lf` bytes > per entry) vs `OpenAddressed` which requires between 5.7 and 13.3 bytes per > entry (due to its load factor variation between 0.3 and 0.7; `4 / lf` per > entry) -- why isn't the JDK using open addressed then you may wonder? Well, > it actually does in its `Set.of` implementation, but not for `HashSet`, > primarily because `HashSet` has less worse edge cases when hash codes are > poor, and it has to be more generally usable (open addressed tables degrade > easier and require more maintenance when under constant modification, which > doesn't apply for us here). makes sense, thanks! ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1316#discussion_r1520069263