Comparing the speed of VCL TTreeView versus Steema TeeTree control.

Comparing the speed of VCL TTreeView versus Steema TeeTree control.
Using excellent Rodrigo Ruz 's RTTI code to fill all types to a Tree:

https://theroadtodelphi.wordpress.com/2010/10/04/fun-with-delphi-rtti-building-a-treeview-with-all-your-classes/

VCL TTreeView : 1900 milliseconds (new updated version, apologies, see comments)

TeeTree : 4 milliseconds !

Source code of test project filling aprox 2000 nodes:

https://drive.google.com/file/d/0BymV3q6di65nTEIyR3dQcVhTMDA/view?usp=sharing

https://drive.google.com/file/d/0BymV3q6di65nTEIyR3dQcVhTMDA/view?usp=sharing

Comments

  1. The VCL tree view is just a wrapper around the Win32 SysTreeView32 control which is known to behave poorly for large trees. However, that code is written very poorly indeed with regards to performance. I'm quite sure that the tree could be populated far far quicker even for a SysTreeView32.

    ReplyDelete
  2. Any chance of comparing Virtual Tree View?

    ReplyDelete
  3. I usually use a non-VCL object Tree with a VirtualOwnerDraw ListBox where Count = CustomTree.VisibleNodeCount. So I can create the new ObjectTree in a Thread, and switch from previous values to new ones instantly.

    ReplyDelete
  4. How about using a not completely retarded way to add the types to the VCL treeview? This takes 1.7 secs on my machine

    function AddRttiTypeHierarchy(ANodes: TTreeNodes; AType: TRttiType): TTreeNode;
    var
      node, child: TTreeNode;
    begin
      if Assigned(AType.BaseType) then
      begin
        node := AddRttiTypeHierarchy(ANodes, AType.BaseType);
        if Assigned(node) then
        begin
          child := node.getFirstChild;
          while Assigned(child) do
          begin
            if child.Data = AType then
              Exit(child);
            child := node.GetNextChild(child);
          end;
          Result := ANodes.AddChildObject(node, AType.Name, AType);
        end
      end
      else
      begin
        Result := ANodes.GetFirstNode;
        if not Assigned(Result) then
          Result := ANodes.AddChildObject(nil, AType.Name, AType);
      end;
    end;


    for lType in TypeList do
      if lType.IsInstance then
        AddRttiTypeHierarchy(TreeViewClasses.Items, lType);

    ReplyDelete
  5. When publishing benchmarks, you need to be really careful not to write crappy code for the variant that you are criticising. Otherwise you look foolish. Please David, correct this.

    ReplyDelete
  6. David Heffernan oops apologies, I just copy/pasted the code, I didn't made the TreeView variant code.

    ReplyDelete
  7. As it stands, you are a commercial software vendor suggesting that your product is wonderful because it is so much faster than the built in tree view. But your evidence is utterly bogus. Please correct this.

    ReplyDelete
  8. I didn't know there was a faster way, apologies again. I've uploaded a new version of the test project to the same link, and modified the post. I guess the slow part of this example is more the Rtti routines than adding nodes to the tree (which is much faster with TeeTree, if there is no extra overhead)

    ReplyDelete
  9. I've made another example, not using rtti. Just adding nodes and subnodes to the trees.

    https://drive.google.com/file/d/0BymV3q6di65neU1pejZfQURGUk0/view?usp=sharing

    Hope I've haven't mistaken, apologies in advance.
    On my machine I get this results:

    VCL TTreeView: 6.5 seconds
    TeeTree : 0.19 seconds

    ReplyDelete
  10. Thanks. I still suspect that the nodes could be added more quickly even for the VCL control. These sort of posts are easy to get wrong. You have to really understand both variants, and be 100% sure you are not misrepresenting the competition.

    ReplyDelete
  11. Thanks. I still suspect that the nodes could be added more quickly even for the VCL control. These sort of posts are easy to get wrong. You have to really understand both variants, and be 100% sure you are not misrepresenting the competition.

    ReplyDelete
  12. I've uploaded a new version of the first project. I've made the same changes Stefan Glienke did for VCL TTreeView in the TeeTree code, and now it's much faster.

    ReplyDelete
  13. This still looks wrong. Populating 2000 nodes in a VCL TTreeView should take around 50ms.

    procedure TForm1.Button1Click(Sender: TObject);
    var
    Stopwatch: TStopwatch;
    i, Depth: Integer;
    Node: TTreeNode;
    begin
    Stopwatch := TStopwatch.StartNew;
    TreeView1.Items.BeginUpdate;
    Depth := 0;
    Node := nil;
    for i := 1 to 2000 do begin
    Node := TreeView1.Items.AddChild(Node, IntToStr(i));
    inc(Depth);
    if Depth=5 then begin
    Node := nil;
    Depth := 0;
    end;
    end;
    TreeView1.Items.EndUpdate;
    Caption := IntToStr(Stopwatch.ElapsedMilliseconds);
    end;

    You really have to get this stuff right.

    ReplyDelete
  14. Yes, the bottleneck is the getfirst/getnext loop to locate a parent node. This is done also with a loop in ttree, but child nodes are in a simple array so the access is faster.

    ReplyDelete
  15. If you wrote the TTreeView code correctly it would not be as slow. It's very bad form to produce a benchmark of your product against another product where you misuse the other product.

    Imagine how you would feel if, for instance, I produced a benchmark of a Steema product that reflected badly on that product because it was being misused. You would be upset. Quite rightly.

    ReplyDelete
  16. I agree, I'm trying to find the best and fastest way to do this example with a TTreeView. The origin of this post was not about speed but a question from Eli M about if TTree could handle many nodes. I then copy/pasted the code and found the big speed difference. Later, Stefan Glienke posted a much improved code which is the one I'm using. I guess the speed problem is more in Microsoft ComCtrls dll than in the VCL wrapper.

    ReplyDelete
  17. I think Delphi's wrapper is pretty reasonable. The comtl32 SysTreeView32 control is not the most performant and really does not scale to large numbers of nodes. I guess that's one reason why MS now use DirectUIHWND in Explorer. You'd be far better off with the sort of code I showed to do perf comparisons. If you bump up the number of nodes you'll soon see that TTreeView slows down. Plot the runtimes for your control against those for TTreeView to show how the runtimes vary with node count. That would be instructive. Forget about the RTTI example. That just gets in the way of the actual benchmark. Use the code in my previous comment, or something similar.

    ReplyDelete
  18. Great ! I'll do that comparison project and post the results here

    ReplyDelete
  19. What I'd expect to see is that TTreeView scales quadratically and a decent control will scale linearly.

    ReplyDelete
  20. Exactly ! I've done the experiment with your code, TTree is very linear (27msec to add 50k nodes) while TTreeView is aprox quadratic (1788msec to add 50k nodes).

    Plot:
    https://drive.google.com/open?id=0BymV3q6di65ncGwwWjZtODhKWm8

    Source code:
    https://drive.google.com/open?id=0BymV3q6di65nTU1DWVFDMURuQjQ

    ReplyDelete
  21. It's easy to predict these things if you already know the answer!!!   ;-)

    ReplyDelete

Post a Comment