How to increase the productivity of populating a massive tree?

First of all, I answer my Q / A question, so I don’t have to answer anyone for this. This is what I learned, and many can use it.

I have a tree structure made up of many different nodes. Each node has an object behind it in the Data property, and objects refer to different levels of the hierarchy from one main list of objects, which is quite large (many thousands of elements). One node represents a specific property of this main listed object, where the tree allows the user to select a node to view those elements that belong to this particular selected category.

When a tree fills up, it becomes extremely time-consuming (in some cases 2 minutes), because each node must iterate over each element in this large list and find every element in this list that matches any given node. Therefore, if there are 500 nodes in this tree, then it repeats this large list 500 times. The total number of hierarchy levels is 3 levels. When loading the second and third levels, a performance throttle occurs, but the first level is simple and fast.

Now there are no options for increasing the repetition performance through this list hundreds of times. I am wondering if there are any known tricks to improve the performance of populating a tree view?

Here's how it works at the moment:

 var X: Integer; N: TTreeNode; O: TMyObject; begin for X := 0 to MyObjectList.Count - 1 do begin O:= TMyObject(MyObjectList[X]); //Object which Node represents N:= TreeView.Items.AddChild(nil, O.Caption); N.Data:= O; LoadNextLevel(N); //Populates child nodes by iterating through master list again end; end; 

And a similar method for each additional level.

PS - The first level of the hierarchy is populated from a separate own list (about 50 objects), while the second and third levels are populated from the properties of these thousands of objects in the main list. That's why the first level loads fast, and the rest is slower.

+7
performance delphi large-data treeview
source share
2 answers

Tree views have a common trick to improve performance in this type of situation. When you update this tree view, load only the first level of the hierarchy and do not worry about any additional levels. Instead, you can load each additional layer during the expansion of each node. Here's how to do it.

When you fill out the first level, rather than continuing to load each of its child nodes, instead just create 1 "dummy" child node with a nil pointer in the Data property - since each node is expected to have an object in the Data property. Then view the OnExpanding event of the tree view. When a node expands, it checks to see if this "dummy" child node exists or not. If so, then he knows that he needs to load child nodes.

When the first hierarchy level loads ...

 var X: Integer; N, N2: TTreeNode; O: TMyObject; begin for X := 0 to MyObjectList.Count - 1 do begin O:= TMyObject(MyObjectList[X]); //Object which Node represents N:= TreeView.Items.AddChild(nil, O.Caption); N.Data:= O; N2:= TreeView.Items.AddChild(N, ''); N2.Data:= nil; //To emphasize that there is no object on this node end; end; 

Then create an event handler for OnExpanding ...

 procedure TForm1.TreeViewExpanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean); var N: TTreeNode; begin N:= Node.getFirstChild; if N.Data = nil then begin //Now we know this is a "dummy" node and needs to be populated with child nodes N.Delete; //Delete this dummy node LoadNextLevel(N); //Populates child nodes by iterating through master list end; end; 

The only drawback of this trick is that all nodes that have not yet been expanded will have + next to them, even if there cannot be child nodes. If so, then when the user clicks the + button to expand the node, the child of the node will be deleted and the + will disappear, so that the user knows that there are no children in this node.

Also, using BeginUpdate and EndUpdate in TreeView.Items improves performance by not having GUI updates until everything is done ...

 TreeView.Items.BeginUpdate; try //Refresh the tree finally TreeView.Items.EndUpdate; end; 
+4
source share

If you really need the fill speed of a massive tree, you should look in virtualTreeView ( http://code.google.com/p/virtual-treeview/ ).
This is an open source tree specifically designed to be virtual and maximize speed / memory for large tree images.
This is an amazing component.

+15
source share

All Articles