On Thu, 10 Sep 2026 20:04:02 GMT, Andy Goryachev <[email protected]> wrote:
>> I fail to understand that. All methods in the `createStyleHelper` will use
>> the parent chain we created once. How could we still end up being quadratic?
>> We will go through the aprent chain, yes, but we did that before as well
>
> ok, this might be a contrived scenario, but it does illustrate the problem.
> the test passes in master and fails with this PR:
>
>
> @Test
> void testQuadraticPerformace() {
> scene.getStylesheets().add(toDataURL(
> """
> .old { -fx-padding: 11; }
> .new { -fx-padding: 22; }
> """));
>
> int depth = 50;
> AtomicInteger count = new AtomicInteger();
>
> class TPane extends Pane {
> private final SimpleStyleableObjectProperty<Font> font;
> private final List<CssMetaData<? extends Styleable, ?>> metadata;
>
> public TPane(CssMetaData<TPane, Font> fontMetadata) {
> font = new SimpleStyleableObjectProperty<>(fontMetadata,
> this, "font", Font.getDefault());
> // we should have a utility for this
> ArrayList<CssMetaData<? extends Styleable, ?>> md = new
> ArrayList<>(Pane.getClassCssMetaData());
> md.add(fontMetadata);
> this.metadata = List.copyOf(md);
> getStyleClass().add("old");
> }
>
> @Override
> public List<CssMetaData<? extends Styleable, ?>> getCssMetaData()
> {
> return metadata;
> }
> }
>
> CssMetaData<TPane, Font> fontMD = new
> FontCssMetaData<TPane>("-fx-font", Font.getDefault()) {
> @Override
> public StyleableProperty<Font> getStyleableProperty(TPane p) {
> count.incrementAndGet();
> return p.font;
> }
>
> @Override
> public boolean isSettable(TPane p) {
> return !p.font.isBound();
> }
> };
>
> ArrayList<TPane> panes = new ArrayList<>(depth);
> TPane top = new TPane(fontMD);
> panes.add(top);
>
> TPane p = top;
> for (int i = 1; i < depth; i++) {
> TPane ch = new TPane(fontMD);
> p.getChildren().add(ch);
> panes.add(ch);
> p = ch;
> }
>
> scene.setRoot(top);
> top.applyCss();
>
> p.getChildren().add(new Pane());
>
> for (TPane pane : panes) {
> pane.getStyleClass().setAll("new");
> }
>
> count.set(0);
>
> p.getChildren().add(new Pane());
>
> int ct = count.get();
> assertTrue(ct <= depth * 4, "Expected<=" + (depth*4) + " observed=" +
> ct + " for depth=" + depth);
> }
Just verified, works with my changes.
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/2225#discussion_r3983149969