JDK-8259558 : Slow Node Referencing
  • Type: Bug
  • Component: javafx
  • Sub-Component: scenegraph
  • Affected Version: openjfx15
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2021-01-09
  • Updated: 2021-03-10
  • Resolved: 2021-03-10
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.
Other
openjfx17Resolved
Related Reports
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
Linux jorge-menezes 5.8.0-36-generic #40~20.04.1-Ubuntu SMP Wed Jan 6 10:15:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

openjdk version "15.0.1" 2020-10-20
OpenJDK Runtime Environment AdoptOpenJDK (build 15.0.1+9)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.24.0-m1, JRE 15 Linux amd64-64-Bit Compressed References 20201207_129 (JIT enabled, AOT enabled)
OpenJ9   - c757b5115
OMR      - 5080dab1e
JCL      - c46d88330c based on jdk-15.0.1+9)


A DESCRIPTION OF THE PROBLEM :
I have an application that increases and decreases the number of nodes for presentation.
It happens that the use of docking is done, so the content of the screen is placed on the side and then you have to return everything as it was, in addition to moving and fitting.

When you change the content from one Pane to Another, it is slow if it has many elements, which is the use case.

In this case, I can't use Canvas because of the mouse control for each element.

The processing is already done, I just want to move things around, I made a small example to summarize what is happening.

I use a large number of Nodes to exemplify the problem of simply referencing.

Please, to test click "change a" and "change b" several times.




STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
After run my program example, click in "change a" and "change b" 

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
slow reference change
ACTUAL -
slow when change reference

---------- BEGIN SOURCE ----------
import java.util.ArrayList;  
import javafx.application.Application;
 
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
 
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane; 
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage;
 
 
public class MoveNodesTest extends Application {
    Scene scene;
    
    BorderPane master = new BorderPane();
    
    HBox hbox =new HBox(80);
    BorderPane bpa1 = new BorderPane();        
    BorderPane bpa2 = new BorderPane();        
    
    
    
    Button init = new Button("Init");       
    Button b = new Button("Change");
    Label  time = new Label();
    
    BorderPane borderNodes = new BorderPane();
    // StackPane sp = new StackPane();
    Pane pane_nodes = new Pane();
    
    boolean one = false;
    
    @Override
    public void start(Stage primaryStage) {
         
        b.setDisable(true);
        borderNodes.setCenter(pane_nodes);
        // sp.getChildren().add(pane_nodes);
         
        master.setCenter(hbox);
        
        hbox.getChildren().addAll(bpa1, bpa2);
        
        master.setLeft(init);
        master.setBottom(b);
        
       
        init.setOnAction( (e) -> {
          until(100000); 
        });
        
        b.setOnAction( (e) -> {
           if(one == false ) {
             
              long tm = System.currentTimeMillis();
              bpa1.setCenter(borderNodes);
              b.setText("Change b");
              one = true;
              
              long res = System.currentTimeMillis() - tm;
              time.setText(""+res+ " ms"); 
               
           }else {
           
             if( one == true) {
              
                long tm = System.currentTimeMillis();
                
                bpa2.setCenter(borderNodes);
                //sp.getChildren().add(pane_nodes);
                b.setText("Change a");
                one = false;
                
                long res = System.currentTimeMillis() - tm;
                time.setText(""+res+ " ms");
                 
             }
             
           }
           
        });
        
        Scene scene = new Scene(master, 700, 600);
        
        primaryStage.setTitle("Move Nodes");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    
      
    private void until(int n) {
       long l1 = System.currentTimeMillis();
       
       ArrayList<Node> nodes = new ArrayList();
       // ObservableList<Node> nodes = FXCollections.observableArrayList();
       
       for(int x=0; x < n; x++) {
          Rectangle rec = new Rectangle(0,0,10,20);  
          rec.setLayoutX(10);
          rec.setLayoutY(10);
          rec.setFill(Color.BLUE);
          Group group = new Group();
          group.getChildren().add(rec);
          nodes.add(rec);
       }
       
       long res = System.currentTimeMillis() - l1;
       
       master.setLeft(time);
       time.setText(""+res+ " ms");
      
       b.setDisable(false);
        
       pane_nodes.getChildren().addAll(nodes);
       
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}


---------- END SOURCE ----------

FREQUENCY : always



Comments
The fix for JDK-8252935 also solves this issue. Closing as Duplicate.
10-03-2021

[~arapte] Based on the following review comment you made: https://git.openjdk.java.net/jfx/pull/185#issuecomment-773869828 I think this bug can be closed as a duplicate of JDK-8252935. Can you confirm this, and close it once verified?
20-02-2021

I expected that adding nodes would take more time than removing them, but the time taken by layout.getChildren().clear() is a lot more compared to layout.getChildren().add(nodes); For example, time taken to remove 100000 nodes is ~1700 ms time taken to add 100000 nodes is ~100 ms I have modified the program to use less controls and more clear messages, please test with attached program: MoveNodesTestV1.java
15-01-2021

Moving to JDK for further evaluation.
11-01-2021