AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Compare Files -> Optimieren

Offene Frage von "cherry"
Ein Thema von cherry · begonnen am 31. Dez 2008 · letzter Beitrag vom 7. Jan 2009
Antwort Antwort
Seite 2 von 2     12   
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#11

Re: Compare Files -> Optimieren

  Alt 2. Jan 2009, 07:55
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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#12

Re: Compare Files -> Optimieren

  Alt 2. Jan 2009, 10:25
Zitat von p80286:
Du verwendest sehr viele write
naja, irgendwie muss ich ja das StringGrid abfüllen... wie soll ich denn das sonst lösen?


Zitat von alzaimar:
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.
zu 1, ist ein bisschen waage ausgedrückt, wie soll ich das denn finden? und überhaupt, hast du dir den code eigentlich angesehen zu 'GetTreeList'?

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?
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#13

Re: Compare Files -> Optimieren

  Alt 4. Jan 2009, 13:57
also, ch hab jetzt noch garnicht groß in deinen QuellCode reingesehn, aber beim ersten Testlauf bekam ich nach nichtmal 'ner Minute dieses hier
Zitat:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt CompareFiles.exe ist eine Exception der Klasse EOutOfMemory aufgetreten. Meldung: 'Zu wenig Arbeitsspeicher'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK Hilfe
---------------------------
gelesene Verzeichnisse ~830
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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#14

Re: Compare Files -> Optimieren

  Alt 5. Jan 2009, 12:18
Zitat von cherry:
... hast du dir den code eigentlich angesehen zu 'GetTreeList'?
Na nee? Wo isser denn?
Zitat von cherry:
zu 2, ja da hast du recht,... Ist das eine StdKomponente von Delphi?
Zitat von alzaimar:
...Und sowas gibt es als 'TStringDictionary' auch hier.
"auch hier" = Suche-Funktion in der Delphi-Praxis.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#15

Re: Compare Files -> Optimieren

  Alt 6. Jan 2009, 06:13
Zitat von alzaimar:
Zitat von cherry:
... hast du dir den code eigentlich angesehen zu 'GetTreeList'?
Na nee? Wo isser denn?
Im ersten Beitrag findest du gleich das ganze Projekt...
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#16

Re: Compare Files -> Optimieren

  Alt 6. Jan 2009, 06:22
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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#17

Re: Compare Files -> Optimieren

  Alt 6. Jan 2009, 06:25
Zitat von alzaimar:
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.
Ist ja praktisch für mich...

Zitat von alzaimar:
Für den Rest habe ich derzeit leider keine Zeit. Heut Abend kann ich mal reinschauen.
Das wäre echt super. Vielen Dank schon mal...
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#18

Re: Compare Files -> Optimieren

  Alt 6. Jan 2009, 15:28
Zitat von p80286:
Du verwendest sehr viele write, und die kosten Zeit!
grüße
K-H
Deshalb habe ich den Code jetzt nochmals ein wenig angepasst...
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 von himitsu:
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.
dieses Problem ist ja auch noch zu lösen, wobei die Idee ja nicht umbedingt ist zwei Festplatten zu überprüfen, oder braucht das jmd?! wie auch immer -> es dürfte keinen Absturz verursachen...

Delphi-Quellcode:
// ]]] 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;
Im Anhang noch das aktualisierte Projekt...
Angehängte Dateien
Dateityp: zip comparefiles_602.zip (23,2 KB, 13x aufgerufen)
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#19

Re: Compare Files -> Optimieren

  Alt 7. Jan 2009, 13:33
Zitat von alzaimar:
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.
Ok, i bin gerade drann das mal mit TStringDictionary resp. mit TIntegerDictionary zu versuchen statt mit meinen Arrays...
Die Klasse habe ich hier gefunden: http://www.delphipraxis.net/internal...ct.php?t=53653

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?
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz