Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

преобразование списка каталогов в древообразный вид [D7, WinXP]


Андрей Молчанов ©   (2005-08-08 18:11:00) 

Здравствуйте!

Необходимо выполнять сабж (для отображения содержимого zip). Колличество файлов ОЧЕНЬ большое. Раньше использовал свой алгоритм, но теперь он перестал устраивать. Как Вы думаете, что можно сделать в плане быстродействия?

Предварительная загрузка путей:

var
 i: integer;
 s: string;
 Structure: array of array of string;
 Node: TTreeNode;
 AddedList: TStringList;
begin
SetLength(Structure, 0);
SetLength(Structure, VCLUnZip.Count);
for i := 0 to VCLUnZip.Count-1 do begin
 s := IncludeTrailingPathDelimiter(VCLUnZip.Pathname[i]);
 while Pos('\', s) > 0 do begin
   if s = '\' then break;
   SetLength(Structure[i], Length(Structure[i]) + 1);
   Structure[i, Length(Structure[i]) - 1] := Copy(s, 0, Pos('\', s) - 1);
   Delete(s, 1, Pos('\', s));
 end;
 SetLength(Structure[i], Length(Structure[i]) + 1);
 Structure[i, Length(Structure[i]) - 1] := VCLUnZip.Filename[i];
end;

//Добавление первого элемента в дерево
AddedList := TStringList.Create;
AddedList.Add('');
CheckTree.Items.BeginUpdate;

CheckTree.Items[0].DeleteChildren;
CheckTree.Items[0].Text := ExtractFileName(edtZipArchive.Text);

for i := 0 to Length(Structure)-1 do begin
 if AddedList.IndexOf(Structure[i, 0]) = -1 then begin
   AddedList.Add(Structure[i, 0]);
   Node := CheckTree.Items.AddChild(CheckTree.Items[0], Structure[i, 0]);
   if Length(Structure[i]) > Node.Level then begin
     Node.ImageIndex := -1;
     Node.SelectedIndex := -1;
     Node.HasChildren := True;
   end else
     SetIconsByExt(ExtractFileExt(Node.Text), Node);
 end;
end;

CheckTree.AlphaSort(True);
CheckTree.Items[0].Expanded := True;
SendMessage(CheckTree.Handle, WM_VSCROLL, SB_TOP, 0);
CheckTree.Items.EndUpdate;
end;


Но все вышеприведенное вызывается только один раз. А вот эта процедура реально тормозит:

procedure TfrmRestoreWizard.CheckTreeExpanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean);
 function StructureTree(X, Y: integer): string;
 var
   i: integer;
 begin
   Result := '';
   for i := Y downto 0 do
     Result := Structure[X, i] + '\' + Result;
 end;
var
 s: string;
 i: integer;
 Child: TTreeNode;
 AddedList: TStringList;
begin
if (Node.getFirstChild = nil) and (Node.Level > 0) then begin
 Screen.Cursor := crHourGlass;
 CheckTree.Items.BeginUpdate;
 s := IncludeTrailingPathDelimiter(MyPathFromNode(Node));
 AddedList := TStringList.Create;
 AddedList.Add('');
 try
   for i := 0 to Length(Structure)-1 do begin
     if (Length(Structure[i]) > Node.Level) and (s = StructureTree(i, Node.Level-1)) then begin
       if AddedList.IndexOf(Structure[i, Node.Level]) = -1 then begin
         AddedList.Add(Structure[i, Node.Level]);
         Child := CheckTree.Items.AddChild(Node, Structure[i, Node.Level]);
         Child.StateIndex := Node.StateIndex;
         if Length(Structure[i]) > Node.Level+1 then begin
           Child.ImageIndex := -1;
           Child.SelectedIndex := -1;
           Child.HasChildren := True;
         end else
           SetIconsByExt(ExtractFileExt(Child.Text), Child);
       end;
     end;
   end;
 finally
   AddedList.Free;
   Node.AlphaSort;
   CheckTree.Items.EndUpdate;
   Screen.Cursor := crDefault;
 end;
end;
end;


Пожалуйста, подскажите. Спасибо.


Андрей Молчанов   (2005-08-09 18:45:00) [1]

Все - вроде дооптимизировал до приемлимого уровня. Спасибо.


WondeRu   (2005-08-09 09:57:00) [2]

Андрей Молчанов   (08.08.05 19:14) [1]
SetIconsByExt(ExtractFileExt(Child.Text), Child);

что это?
Если проставление иконок для узлов, то торррмозоа тебе гарантированы ;)


Суслик   (2005-08-09 09:54:00) [3]

ты используешь TStringList?

Поставь у него флажок sorted.

Тогда


> AddedList.IndexOf(Structure[i, Node.Level]) = -1


это будет существенно быстрей работать.


Андрей Молчанов   (2005-08-08 20:17:00) [4]

Спасибо исправлю, но... тормозит вот в этом месте, при проверке условий в цикле, т.к. Length(Structure)-1 достаточно большой (несколько тысяч).


 for i := 0 to Length(Structure)-1 do begin
   if (Length(Structure[i]) > Node.Level) and (s = StructureTree(i, Node.Level-1)) then begin
     if AddedList.IndexOf(Structure[i, Node.Level]) = -1 then begin         AddedList.Add(Structure[i, Node.Level]);
       ...
     end;
   end;
 end;


Суслик   (2005-08-08 20:04:00) [5]

Если нет возможности сразу определить длину массива (честно говоря лень код разбирать) то пользуйся TSTringList и добавляй по одному элементу. Там проведена оптимизация в целях ускорения добавления по одному элементу.


Суслик   (2005-08-08 20:03:00) [6]


> SetLength(Structure[i], Length(Structure[i]) + 1);

не делай так.

Выделяй сразу

SetLength(Structure[i], ...count...)

дальше заполняй.

Когда дин. массив заполняешь по одному элементу - это сильно тормозит.


Андрей Молчанов   (2005-08-08 19:14:00) [7]

Вот еще: насколько я понял, основные тормоза вот здесь:
  for i := 0 to Length(Structure)-1 do begin
    if (Length(Structure[i]) > Node.Level) and (s = StructureTree(i, Node.Level-1)) then begin
      if AddedList.IndexOf(Structure[i, Node.Level]) = -1 then begin
        AddedList.Add(Structure[i, Node.Level]);
        Child := CheckTree.Items.AddChild(Node, Structure[i, Node.Level]);
        Child.StateIndex := Node.StateIndex;
        if Length(Structure[i]) > Node.Level+1 then begin
          Child.ImageIndex := -1;
          Child.SelectedIndex := -1;
          Child.HasChildren := True;
        end else
          SetIconsByExt(ExtractFileExt(Child.Text), Child);
      end;
    end;
  end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо