プロパティをtrueに設定したwinformsTreeViewコントロールがあります。また、プロパティにインスタンスを割り当てて、デフォルトのソーターをオーバーライドします。SortedIComparerTreeViewNodeSorter
残念ながら、この関数を使用して数千のノードを追加するには、AddRangeおそらく10秒かかります。Sortedfalseに設定すると、AddRange関数は1/2秒未満になります。(非常に多くのノードを追加することの有効性については議論しないでください)
ああ、あなたが言うのを聞きます..私のIComparerオブジェクトに問題があります。プロファイラーによるとではありません。ソートオブジェクトに費やされる時間はほとんどありませんが、そのAddRange関数は低速関数のリストの一番上にあります。
この問題は、テストプロジェクトで簡単に再現できます。のリストを作成し、関数TreeNodeを使用して既存の拡張ツリーノードに追加するだけです。AddRangeこれにより、ツリーテキストのデフォルトの並べ替えが使用されます。これも不釣り合いに遅いです。
Sortedテストprobjectでプロパティを無効にしList<T>.Sort、ノードをツリーに追加する前にノードのリストで関数(ノードのテキストを比較するデリゲートを使用)を使用すると、どれほど遅くなるかを示すために、実質的に遅延はありません。
これは、を使用する前にノードを手動でソートする回避策につながりAddRangeます。Sortedそれは問題ありませんが、既存の子ノードのセットにノードを追加するときに正しい挿入ポイントを見つけるには多くの作業が必要になります。単にtrueに設定するよりも便利ではありません。
とにかく行動をスピードアップする方法はありますか?
編集-追加する前にソートするのが唯一の方法のようです..少し面倒ですが、私は次の拡張メソッドを思いつきました:
public static void AddSortedRange(this TreeNodeCollection existingNodes, IList<TreeNode> nodes, TreeView treeView, IComparer sorter)
{
TreeNode[] array = new TreeNode[nodes.Count + existingNodes.Count];
existingNodes.CopyTo(array, 0);
nodes.CopyTo(array, existingNodes.Count);
Array.Sort(array, sorter);
treeView.BeginUpdate();
existingNodes.Clear();
existingNodes.AddRange(array);
treeView.EndUpdate();
}
既存のノードを配列にコピーし、新しいノードを追加し、配列を並べ替えてから、ツリービューでノードをインラインで操作しようとするものを置き換える方が高速です-上記のコードで最も遅い操作はexistingNodes.Clear()呼び出しです