![]() |
Re: Compare Files -> Optimieren
Neben dem Logging (per 'Write') würde ich folgende Operationen als Performancebremse ansehen:
1. 'GetTreeList' 2. 'arFileRecIndexOfDir'. Bei (1) hilft ein schnelleres Verfahren zum Auslesen einer Verzeichnisstruktur (gibts hier oder im der Delphi-Forum, weiss nicht mehr genau) Bei (2) wäre der Code interessant. Ich tippe auf eine einfache For-Schleife und das kann man wesentlich schneller machen, z.B. durch eine Hashmap. Und sowas gibt es als 'TStringDictionary' auch hier. |
Re: Compare Files -> Optimieren
Zitat:
Zitat:
zu 2, ja da hast du recht, is nur eine for schleiffe... werde mich mal mit sonem 'TStringDictionary' versuchen anzufreunden, habe ich allerdings noch nie verwendet. Ist das eine StdKomponente von Delphi? |
Re: Compare Files -> Optimieren
also, ch hab jetzt noch garnicht groß in deinen QuellCode reingesehn, aber beim ersten Testlauf bekam ich nach nichtmal 'ner Minute dieses hier
Zitat:
Speicher laut Taskmanager ~190 MB (von deinem Programm) und insgesamt noch knapp 1,5 GB frei Insgesamt würde es, von der Programmstruktur und den verwendeten Komponenten her, vermutlich aber eh Probleme mit vielen Dateien geben (war es wohl nicht sonderlich gut, von mir, deinem Programm gleich mal 2 "kleine" Festplatten zum Vergleich zu geben) Beim 2. Versuch, nur mit meinem USB-Stick und seinem Backup (je 26.506 Dateien und ~2 GB belegt) kommt der selbe Fehler. nja, auch wenn es nicht jeder baucht ... mit den japanischen, russischen und ähnlichen Dateinamen auf meinem Plättchen gib es sowieso Probleme. PS: Pegasus (Luckie), hSync (/me) und Weitere, derartige Programme findest in der DP [add] unter 100 Dateien in 'nem Verzeichnis scheint der Vergleich erstmal korrekt zu funktionieren |
Re: Compare Files -> Optimieren
Zitat:
Zitat:
Zitat:
|
Re: Compare Files -> Optimieren
Zitat:
|
Re: Compare Files -> Optimieren
Oh. Gut. Die Standard-Vorgehensweise. Hier oder im Delphi-Forum wurde ein kleiner Wettbewerb gestartet, welches Tool denn nun schneller ist (um Dateinamen zu suchen). Die Vorgehensweise könnte Dir jedoch helfen, denn 'FindFirst/FindNext' hat wohl einen ganz schönen Overhead.
Für den Rest habe ich derzeit leider keine Zeit. Heut Abend kann ich mal reinschauen. |
Re: Compare Files -> Optimieren
Zitat:
Zitat:
|
Re: Compare Files -> Optimieren
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
allerdings spare ich nicht allzuviel Zeit ein. Bei meinem vergleich mit ~10'000 und ~2'000 Ordnern war das Programm jetzt immerhin 2 Sekunden schneller und brauchte aber insgesammt immer noch 6 Sekunden. Das ist aber immer noch min. 2 Sekunden zu langsam und Zitat:
Delphi-Quellcode:
Im Anhang noch das aktualisierte Projekt...
// ]]] START COMPARING [[[
procedure TFormMain.Compare; var i,j,c,tmpIndex,tmpIndex2,ri:Integer; Dir:String; // Directory Name arChecked: array of Integer; arRow: TRowArray; begin ClearStringGrid; SetLength(arFileRec1,0); SetLength(arFileRec2,0); SetLength(arChecked,0); SetLength(arRow,0); Dir:=''; c:=0; // files count abort:=false; GetTreeList(DirectoryListBox1.Directory, DirectoryListBox1.Directory, '*', CbSubDirs.Checked, True, arFileRec1); GetTreeList(DirectoryListBox2.Directory, DirectoryListBox2.Directory, '*', CbSubDirs.Checked, False, arFileRec2); for i := low(arFileRec1) to high(arFileRec1) - 1 do begin // Application.ProcessMessages; // if abort then // exit; if (Dir <> arFileRec1[i].Dir) then begin Dir:=arFileRec1[i].Dir; SetLength(arRow,Length(arRow)+1); arRow[Length(arRow)-1].Name:=Dir; end; ri:=Length(arRow); SetLength(arRow,ri+1); arRow[ri].Name:=arFileRec1[i].Name; arRow[ri].Size:=IntToStr(arFileRec1[i].Size); arRow[ri].Date:=DateTimeToStr(arFileRec1[i].Date); tmpIndex:=ArFileRecIndexOfDirName(arFileRec2,arFileRec1[i].DirName); Inc(c); if (tmpIndex <> -1) then begin // remember the values already checked ... SetLength(arChecked,Length(arChecked)+1); arChecked[Length(arChecked)-1]:=tmpIndex; // at least compare date values ... case CompareDate(arFileRec1[i].Date,arFileRec2[tmpIndex].Date) of fdsNewer: begin arRow[ri].Sign:='>'; end; fdsOlder: begin arRow[ri].Sign:='<'; end; fdsSameDate: begin arRow[ri].Sign:='='; end; end; arRow[ri].Date2:=DateTimeToStr(arFileRec2[tmpIndex].Date); arRow[ri].Size2:=IntToStr(arFileRec2[tmpIndex].Size); arRow[ri].Name2:=arFileRec2[tmpIndex].Name; end else begin arRow[ri].Sign:='>'; tmpIndex2:=arFileRecIndexOfDir(arFileRec2,arFileRec1[i].Dir,0); if tmpIndex2 <> -1 then begin for j := tmpIndex2 to high(arFileRec2) - 1 do begin if not IntArray_Contains(arChecked,j) then begin if arFileRecIndexOfDir(arFileRec2,arFileRec1[i].Dir,j) <> -1 then begin if (arFileRecIndexOfDirName(arFileRec1,arFileRec2[j].DirName) = -1) and (arFileRec1[i].Dir = arFileRec2[j].Dir) then begin arRow[ri].Sign:='<'; arRow[ri].Date2:=DateTimeToStr(arFileRec2[j].Date); arRow[ri].Size2:=IntToStr(arFileRec2[j].Size); arRow[ri].Name2:=arFileRec2[j].Name; // remember the values already checked ... SetLength(arChecked,Length(arChecked)+1); arChecked[Length(arChecked)-1]:=j; Inc(c); end end else break; end; end; end; end; end; Dir:=''; // maby there exists folders unique on the right ... for i := low(arFileRec2) to high(arFileRec2) - 1 do begin // Application.ProcessMessages; // if abort then // exit; if not IntArray_Contains(arChecked,i) then begin if (Dir <> arFileRec2[i].Dir) then begin Dir:=arFileRec2[i].Dir; SetLength(arRow,Length(arRow)+1); arRow[Length(arRow)-1].Name:=Dir; end; ri:=Length(arRow); SetLength(arRow,ri+1); arRow[ri].Sign:='<'; arRow[ri].Date2:=DateTimeToStr(arFileRec2[i].Date); arRow[ri].Size2:=IntToStr(arFileRec2[i].Size); arRow[ri].Name2:=arFileRec2[i].Name; Inc(c); end; end; Statusbar1.Panels[0].Text := ' files found: '+IntToStr(c); BtnCompare.Enabled:=True; BtnAbort.Enabled:=False; StringGrid1.RowCount:=Length(arRow); for i := 1 to Length(arRow) do begin StringGrid1.Cells[0,i]:=arRow[i].Name; StringGrid1.Cells[1,i]:=arRow[i].Size; StringGrid1.Cells[2,i]:=arRow[i].Date; StringGrid1.Cells[3,i]:=arRow[i].Sign; StringGrid1.Cells[4,i]:=arRow[i].Date2; StringGrid1.Cells[5,i]:=arRow[i].Size2; StringGrid1.Cells[6,i]:=arRow[i].Name2; end; end; |
Re: Compare Files -> Optimieren
Zitat:
Die Klasse habe ich hier gefunden: ![]() Nur habe ich ein grosses Problem: Ich kappier nicht ganz wie die funzt. Zunächstmal wenn ich einen Wert adden will mit der Procedure Add(aKey: Cardinal; aData: Pointer) ... Wieso einen Pointer, ich will doch einen Stringwert hineinschreiben?! wie mach ich das nun? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz