On Mon, 7 Sep 2026 13:10:10 GMT, Marius Hanl <[email protected]> wrote:
>> ok, so here is the test that passes in master and fails spectacularly with
>> this PR:
>>
>>
>> @Test
>> void checkQuadraticPerformace() {
>> scene.getStylesheets().add(toDataURL(
>> """
>> .old {
>> -fx-padding: 1.0;
>> }
>> .new {
>> -fx-padding: 99.0;
>> }
>> """));
>>
>> AtomicInteger counter = new AtomicInteger();
>>
>> class TPane extends Pane {
>> public TPane(String style) {
>> getStyleClass().add("style");
>> }
>>
>> @Override
>> public Styleable getStyleableParent() {
>> counter.incrementAndGet();
>> return super.getStyleableParent();
>> }
>> }
>>
>> int number = 16;
>> ArrayList<TPane> chain = new ArrayList<>();
>>
>> TPane top = new TPane("old");
>> chain.add(top);
>>
>> TPane p = top;
>> for (int i = 1; i < number; i++) {
>> TPane ch = new TPane("old");
>> p.getChildren().add(ch);
>> chain.add(ch);
>> p = ch;
>> }
>>
>> scene.setRoot(top);
>> top.applyCss();
>>
>> counter.set(0);
>> // mark the chain dirty
>> p.getChildren().add(new Pane());
>> int baseline = counter.get();
>>
>> for (TPane pane : chain) {
>> pane.getStyleClass().setAll("new");
>> }
>>
>> counter.set(0);
>> // should not result in quadratic performance
>> p.getChildren().add(new Pane());
>> int newCount = counter.get();
>>
>> assertTrue(newCount <= baseline * 4, () -> {
>> return MessageFormat.format("Baseline={0}, observed={1}",
>> baseline, newCount);
>> });
>> }
>
> Thanks, very helpful! I thought about it for a while, and did come up with
> another implementation that I think is a bit more simple and the other hand
> more optimized for that scenario.
>
> Now I will collect all nodes just once and reuse that list to initialize all
> stale `styleHelper`. That should be much more optimized and I actually think
> it improved the code as well a little bit.
> I first thought this may get much more complex, but it isn't IMO.
(Also added your test as regression test!)
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/2225#discussion_r3950040750