clearing a treeview

Please discuss general Delphi programming topics here.

clearing a treeview

Postby safran » December 17th, 2008, 5:42 pm

Hi,
I have a form with a treeview and 2 buttons
On the forms OnCreate event, an XML file is loaded into the treeview
The code is timed and displayed in the statusbar1.Panels[0]
Clicking the first button clears the treeview, this code is also timed and is displayed in the statusbar1.Panels[1]
Clicking the second button reloads the XML file into the treeview
Again, the code is timed and is displayed in the statusbar1.Panels[2]

The timings for the loading, clearing and reloading are :
1220 verbs : 0,378 seconds
Cleared in : 13,7 seconds
1220 verbs : 0,972

Obviously, there is a few milliseconds difference each time I run the program

My question is why does it take almost 14 seconds to clear the treeview. If I just close the form by clicking the X in the top right hand corner, Delphi closes normally after freeing memory, cleaning up etc. in 1 or 2 seconds.
I don't need to clear the data in my project, I'm curious to know what delphi is doing for 14 seconds.

The code for the form OnCreate event and the reload button is the same except for the statusbar1.Panels
The clear treeview code is just
TreeView1.Items.Clear;
with the timing code.

I like your site - it has a clean and simple layout. I hope to use your MRU code in this project of mine. At the moment, I am playing around with Delphi whilst learning BDS 2006
Thanks for and help in advance but again, it is not important, I'm just curious

Code: Select all
procedure TForm4.FormCreate(Sender: TObject);
var
  pList: IXMLTree2xmlType;
  i: integer;
  aTreeNode: TTreeNode;
  Freq, StartCount, StopCount: Int64;
  TimingSeconds: double;
begin
  pList := Gettree2xml(XMLDocument1);

  TreeView1.Items.BeginUpdate;

  QueryPerformanceFrequency(Freq);
  QueryPerformanceCounter(StartCount);

  for i := 0 to pList.Count - 1 do
  begin
    aTreeNode := TreeView1.Items.Add(nil,pList.VMot[i].iVerb);
    TreeView1.Items.AddChild(aTreeNode,pList.VMot[i].eVerb);

    QueryPerformanceCounter(StopCount);
    TimingSeconds := (StopCount - StartCount) / Freq;

    TreeView1.Items.EndUpdate;

    TreeView1.Items[0].Selected := true;
    StatusBar1.Panels[0].Text := (' ' + inttostr(pList.Count - 1) + ' verbs : ' + FloatToStrF(TimingSeconds, ffGeneral, 3, 2) + ' seconds');
  end;
end;



Code: Select all
procedure TForm4.Button2Click(Sender: TObject);
var
  Freq, StartCount, StopCount: Int64;
  TimingSeconds: double;
begin
  QueryPerformanceFrequency(Freq);
  QueryPerformanceCounter(StartCount);

  TreeView1.Items.Clear;

  QueryPerformanceCounter(StopCount);
  TimingSeconds := (StopCount - StartCount) / Freq;
  StatusBar1.Panels[1].Text := (' Cleared in... ' + FloatToStrF(TimingSeconds, ffGeneral, 3, 2) + ' seconds');
end;
safran
Member
Member
 
Posts: 3
Joined: December 17th, 2008, 9:29 am
Location: France

Re: clearing a treeview

Postby w2m » December 17th, 2008, 8:35 pm

Try this:
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
TreeView1.Items.EndUpdate;

Any difference?
w2m
w2m
Senior Member
Senior Member
 
Posts: 76
Joined: March 8th, 2003, 7:11 pm
Location: New York, USA

Re: clearing a treeview

Postby safran » December 19th, 2008, 10:17 am

Hi,
Thank you w2m for the quick response. When I googled "beginupdate delphi", the first response I got was:

If you use a Delphi component like a ListBox, Memo, TreeList, ListView,... and you add or modify a lot of items (lines, nodes,...), the component's performance becomes very slow. This is due to the fact that after each change, it is redrawn on the screen. Thus, modifying 10000 items of a ListBox causes 10000 redraws, and that takes from several seconds to several minutes, depending on the computer's speed and the complexity of the process.

OK So I added a memo and button to the form with the following code + the timing code
Code: Select all
  Memo1.Lines.BeginUpdate;
  for i := 1 to 5000 do
    Memo1.Lines.Add('abcd');
  Memo1.Lines.EndUpdate;


The timings were 0,707 seconds with the beginupdate
and 5,78 seconds without the beginupdate

So the code works but not for the original treeview. If I figure out what I'm doing wrong I'll let you know

Thanks again
safran
Member
Member
 
Posts: 3
Joined: December 17th, 2008, 9:29 am
Location: France

Re: clearing a treeview

Postby Kambiz » December 19th, 2008, 3:13 pm

  1. When you call TreeView.Items.Clear, Delphi internally calls BeginUpdate and EndUpdate of the control.
  2. Delphi only sends a windows message to the TreeView to clear its nodes. It's Windows that clears the nodes.
  3. Delphi receives notification from Windows about deleted nodes, and then deletes the node object.
Therefore, you can only do a few things to speed up node removal, but just a few milliseconds:

  1. Use a faster memory manager like FastMM to speed up deleting the node object.
  2. Remove OnDeletion event handler. If you have attached data to each node, you must release their allocated memory before clearing nodes.
  3. Before deleting, set SelectedNode to a the first root node. After deleting the selected node, TreeView tries to select another node. Let that node be the last one.
Even releasing the TreeView and recreating a clone of the old one does not solve the problem. To check it out by yourself, declare a MemoryStream in your form, and use the following code:

Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
begin
  Stream := TMemoryStream.Create;
  Stream.WriteComponent(MyTreeView);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Stream.Free;
end;

procedure TForm1.ClearTreeView;
var
  NewTreeView: TTreeView;
begin
  NewTreeView := TTreeView.Create(TreeView1.Owner);
  NewTreeView.BoundsRect := TreeView1.BoundsRect; // to prevent flickering
  NewTreeView.Parent := TreeView1.Parent;
  TreeView1.Free;
  Stream.Position := 0;
  Stream.ReadComponent(NewTreeView);
  TreeView1 := NewTreeView;
end;

Seems you have to use a third party TreeView control or use TreeView in virtual mode.
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Re: clearing a treeview

Postby safran » December 25th, 2008, 6:53 pm

Thank you Kambiz for your response.
safran
Member
Member
 
Posts: 3
Joined: December 17th, 2008, 9:29 am
Location: France


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron