2

私は VirtualTreeView に依存して、時折変更される何千ものアイテムを表示します。これが発生すると、ツリーはクリーンアップされ、再び取り込まれます。

並べ替えは自動的に行われますが (toAutoSortフラグが設定されます)、これにはすべてのノードを再帰的に初期化するという望ましくない効果があり、ご想像のとおり、これは非常にコストのかかる操作です。

.Sortでは、いつメソッドを呼び出す必要toAutoSortがありますか? (DoInitChildren はもっともらしく見えましたが、ときどき結果が逆になるなどの奇妙な結果が得られたので、子を並べ替えるには良いイベントではないと思います。)

4

2 に答える 2

4

この種のシナリオの一般的なルールは、すべての新しい項目が追加された後に並べ替えることです。そうすれば、並べ替え (および初期化) を 1 回だけ行うことができます。

于 2010-03-10T03:54:51.533 に答える
1

ツリー全体が毎回完全に異なる場合を除き、ツリーをクリアするのではなく、アイテムの新しいリストを個別に作成し (アイテムの識別のみ)、そのリストを並べ替えてから、両方のツリーを順番にたどることで、パフォーマンスを向上させることができます。 . 一般的なアルゴリズムは次のようになります (左側のリストは「新しいリスト」で、右側のリストは「既存のリスト」です)。

LeftCur := 0;
RightCur := 0;
while (LeftCur < TotalLeft) and (RightCur < TotalRight) then
  begin
    if LeftList[LeftCur] = RightList[RightCur] then
      begin
        // matches, so just advance 
        Inc(LeftCur);
        Inc(RightCur);            
      end
    else if LeftList[LeftCur] < RightList[RightCur] then
      begin
        // insert happens BEFORE RightCur
        InsertLeftItemToRight;
        Inc(RightCur);
        Inc(TotalRight);
      end
    else if LeftList[LeftCur] > RightList[RightCur] then
      begin
        DeleteRightItem;
        Dec(TotalRight);
      end;
  end;
  While RightCur < TotalRight do
    begin
      DeleteRightItem;
      Dec(TotalRight);
    end;
  While LeftCur < TotalLeft do
    AppendLeftItemToRight;

このようにして、リストはソートされたままになり、InsertLeftItemToRight ステップでアイテムのロードを完了するだけで済みます。ツリーでは、一致するたびに、子に対して同様のルーチンを実行します。この概念は、既存のリスト内のアイテムがあまり変更されない、または完全にロードするのに費用がかかる可能性があるという事実に対して重み付けされています。

于 2010-03-10T17:02:01.453 に答える