VirtualTreeview: когда сортировать детей? - PullRequest
2 голосов
/ 10 марта 2010

Я полагаюсь на VirtualTreeView, чтобы отображать тысячи элементов, которые должны периодически меняться, и когда это происходит, дерево очищается и заполняется снова.

Сортировка выполняется автоматически (установлен флаг toAutoSort), но это приводит к нежелательному эффекту рекурсивной инициализации всех узлов, и это очень дорогая операция, как вы можете себе представить.

Так когда же мне вызывать метод .Sort, когда toAutoSort выключен? (DoInitChildren выглядело правдоподобно, но я иногда получал странные результаты, например, обратные результаты, поэтому я полагаю, что сортировка детей не годится).

Ответы [ 2 ]

4 голосов
/ 10 марта 2010

Общее правило в этом сценарии - сортировка после добавления всех новых элементов. Таким образом, вы сортируете (и инициализируете) только один раз.

1 голос
/ 10 марта 2010

Если все дерево полностью не меняется каждый раз, вы можете получить лучшую производительность, не очищая дерево, а создавая отдельно новый список элементов (просто идентифицируя элементы), сортируя этот список, затем обходя оба дерева порядок ... общий алгоритм выглядит примерно так (левый список - это «новый список», а правый список - «существующий список»):

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. В дереве, когда вы подходите, вы запускаете аналогичную процедуру для детей. Эта концепция основана на том факте, что элементы в существующем списке не будут сильно меняться или могут стоить полной загрузки.

...