PDA

Ver la Versión Completa : Mi aplicacion estas mui lenta


Paulao
06-03-2012, 17:04:15
Quando hago una busca en un universo de unos 2.000 archivo(.pas y .dfm), se queda mui lenta mi aplicacion. Abajo mis codigos:

Mi procedure de busca
procedure TForm1.BuscaTexto(path: string; const FileMask, tipo, tabela: string);
var
SR: TSearchRec;
txt: TextFile;
Row: string;
Found: Boolean;
i: Integer;
NroExt: TStrings;
begin
NroExt:= TStringList.Create;
try
Varrer.Enabled := False;
NroExt.Delimiter:= ';';
NroExt.DelimitedText:= FileMask;
path := IncludeTrailingPathDelimiter(path);
for i:= 0 to NroExt.Count - 1 do
begin
if FindFirst(path + NroExt[i], faAnyFile - faDirectory, SR) = 0 then
repeat
Application.ProcessMessages;
AssignFile(txt,path + SR.Name);
Reset(txt);
Found:= False;
while not Eof(txt) and not Found do
begin
Readln(txt, Row);
if Pos(tabela, Row) > 0 then
begin
ListBox1.Items.Add(tipo + ';' + tabela + ';' + SR.Name);
Found:= True
end
end;
CloseFile(txt);
until FindNext(SR) <> 0
end;
finally
NroExt.Free;
Varrer.Enabled := True;
FindClose(SR);
end;
//end;

if FindFirst(Path + '*.*', faDirectory, SR) = 0 then
begin
try
repeat
if (SR.Name <> '.') and (SR.Name <> '..') then
TextFoundInFile(Path + SR.Name,'*.pas;*.dfm',tipo,tabela);
until FindNext(SR) <> 0;
finally

end;
end;
end;

Mi llamada a procedure
procedure TForm1.VarrerClick(Sender: TObject);
begin
ClientDataSet1.Open;
pth := IncludeTrailingPathDelimiter(edtDir.Directory);
while not ClientDataSet1.Eof do
begin
//TextFoundInFile(pth,'*.pas;*.dfm',ClientDataSet1.FieldByName('xtype').AsString,ClientDataSet1.FieldB yName('name').AsString);
BuscaTexto(pth,'*.pas;*.dfm',ClientDataSet1.FieldByName('xtype').AsString,ClientDataSet1.FieldByName ('name').AsString);
ClientDataSet1.Next;
end;
ListBox1.Items.SaveToFile(ExtractFilePath(Application.ExeName) + 'Fontes.csv');
end;

Casimiro Notevi
06-03-2012, 18:36:13
Así a simple vista me parece que haces un bucle que repites tantas veces como ficheros hay. ¿Puede ser?

ecfisa
06-03-2012, 19:23:13
Hola Paulao.

La acción que realiza el algorítmo, leer cada línea de cada archivo .pas y .dfm hasta encontrar la palabra buscada, como toda búsqueda secuencial, es intrínsecamente lenta y por supuesto su tiempo de ejecución está relacionada en forma directa a la cantidad de archivos a revisar.

Creo también, que haber modificado la función por procedimiento e incluir la carga del TListBox dentro de la misma hace que todo sea un poco más lento. Así que retomando la función original (http://www.clubdelphi.com/foros/showthread.php?t=77761), yo probaría si mejora el rendimiento de este modo:


function TForm1.TextFoundInFile(Ruta: string; const FileMask, Buscado, tipo: string): TStrings;
var
SR: TSearchRec;
txt: TextFile;
Row: string;
Found: Boolean;
NroExt: TStrings;
i: Integer;
begin
NroExt:= TStringList.Create;
try
NroExt.Delimiter:= ';';
NroExt.DelimitedText:= FileMask;
Ruta:= IncludeTrailingPathDelimiter(Ruta);
Result:= TStringList.Create;
for i:= 0 to NroExt.Count - 1 do
begin
if FindFirst(Ruta + NroExt[i], faAnyFile - faDirectory, SR) = 0 then
repeat
Application.ProcessMessages;
AssignFile(txt, Ruta + SR.Name);
Reset(txt);
Found:= False;
while not Eof(txt) and not Found do
begin
Readln(txt, Row);
if Pos(Buscado, Row) > 0 then
begin
Result.Add(tipo + ';' + Buscado + ';' + SR.Name);
Found:= True
end
end;
CloseFile(txt);
until FindNext(SR) <> 0
end
finally
NroExt.Free
end
end;


LLamada:

...
ListBox1.Items:= TextFoundInFile( pth,'*.pas;*.dfm',
ClientDataSet1.FieldByName('xtype').AsString,
ClientDataSet1.FieldByName('name').AsString);
...

Pero como te mencioné arriba, las búsquedas secuenciales son de por sí lentas y si sumamos a eso la lectura secuencial del DataSet...

Un saludo.