AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Eindeutiger Vergleich für große Dateien gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

Eindeutiger Vergleich für große Dateien gesucht

Ein Thema von dahead · begonnen am 2. Aug 2005 · letzter Beitrag vom 10. Mai 2014
Antwort Antwort
Seite 5 von 12   « Erste     345 67     Letzte »    
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#41

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 01:32
@negaH:

gerade lese ich noch einen beitrag von dir über RPNG's (stichwort: radioaktiver zerfall), und da kommt schon wieder eine antwort auf diesen thread, danke!

zum thema: ja, memory mapped files habe ich in diesem zusammenhang auch schonmal gehört (genauer gesagt heute mittag, als ich nach einer schnellen möglichkeit für den byte-per-byte vergleich gesucht habe: efg MMF), muss aber zugeben, dass ich dieses 'system' noch nie verwendet. hätte ich mir wohl genauer ansehen sollen.

danke für deinen code! ich werde ihn mir morgen früh mal genauer ansehen und testen.
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#42

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 01:37
moin hagen,

ich denke nicht, das man mit diesen Funktionen einen wesentlichen Geschwindigkeitszuwachs erzielen wird,
finde aber FileOpen() logischer und einfacher zu Hand haben. (zwecks Portierung wirst du damit keine Probleme bekommen, mit der API vielleicht schon)
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#43

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 01:41
also ich habe während ich vorhin den o.g. beitrag von negaH gelesen habe, einen test mit TFileStream laufen lassen.

dabei wurden wieder die beiden doppelten dateien verglichen (s. screenshot irgendwo vorne). dauer ca. 700 sekunden.
edit: also byte-per-byte.

gerade habe ich negaH's code eingebaut und der vergleich dauert 3,44 sekunden.

erstaunlich. ich muss mir mal die hilfe zu den api befehlen (CreateFileMapping, usw.) ansehen, damit ich genauer verstehe, was sich hinter memory mapped files genau verbirgt.

edit2: falls du es auch testen willst, hier der entsprechende code (ohne negaH's o.g. code. den habe ich einfach mal in die unit mit reinkopiert. einzige änderung war, dass ich Tmmf in TMemoryMappedFile umbenannt habe):

Delphi-Quellcode:
function Tmf.FilesAreBinaryEqual(const File1, File2: String): Boolean;
const
  BlockSize = 65536;
var
  //FSFile1, FSFile2: TFileStream;
  FSFile1, FSFile2: TMemoryMappedFile;
  L1, L2: Integer;
  B1, B2: Array[1..BlockSize] of Byte;
begin
  Result := False;
  //FSFile1 := TFileStream.Create(File1, fmOpenRead or fmShareDenyWrite);
  FSFile1 := TMemoryMappedFile.Create(File1);
  try
    //FSFile2 := TFileStream.Create(File2, fmOpenRead or fmShareDenyWrite);
    FSFile2 := TMemoryMappedFile.Create(File2);
    try
      if FSFile1.Size = FSFile2.Size then
      begin
        while FSFile1.Position < FSFile1.Size do
        begin
          L1 := FSFile1.Read(B1[1], BlockSize);
          L2 := FSFile2.Read(B2[1], BlockSize);
          if L1 <> L2 then
            Exit;
          if not CompareMem(@B1[1], @B2[1], L1) then
           Exit;
        end;
        Result := True;
      end;
    finally
      FSFile2.Free;
    end;
  finally
    FSFile1.Free;
  end;
end;
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#44

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 01:45
Das hört sich doch sehr gut.
Könnte gut möglich sein, dass das mit der Auslagerungsdatei zusammenhängt.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#45

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 11:08
@DaHead:

denoch machst du den Vergleich sehr umständlich !

Delphi-Quellcode:
      if FSFile1.Size = FSFile2.Size then
      begin
        while FSFile1.Position < FSFile1.Size do
        begin
          L1 := FSFile1.Read(B1[1], BlockSize);
          L2 := FSFile2.Read(B2[1], BlockSize);
          if L1 <> L2 then
            Exit;
          if not CompareMem(@B1[1], @B2[1], L1) then
           Exit;
        end;
        Result := True;
das geht einfacher mit

  result := (FSFile1.Size = FSFile2.Size) and CompareMem(FSFile1.Memory, FSFile2.Memory, FSFile1.Size); Denn das MMF hat ja schon die komplette Datei in den Speicher virtuell eingeblendet.
Du musst halt nur aufpassen das die beiden Dateien NICHT zu groß sind. Eine 2 Gb Datei wird man eben nicht vollständig in den Speicher einblenden können. Um denoch mit MMF's arbeiten zu können musst du dann aber mit MapViewOfFile() die Startposition + Pagegröße aus der Zieldatei stückchenweise einblenden. Am besten du baust dir eine reine API-Funktion die über das Windows-API + MMF's zwei Dateien binär vergleicht, also ohne VCL.

Schneller ist das weil du immer mehr auf Zwischengepufferte Daten verzichtest, sprich keinerlei Caches und Speicherkopierungen mehr durchgeführt werden. Das OS lädt nämlich ohne Umwege die Datei in den Speicher.

Aber 3,44 im Verhältnis zu 700 Sekunden hätte ich weis Gott nicht vermutet, da hätte ich Bigg mit seiner Aussage ebenfalls Recht gegeben. Bist du dir sicher das du auch wirklich die kompletten Dateien verglichen hast ? Schiebe mal ein FSFile1.Position := 0; und FSFile2.Position :=0; mit rein, oder benutze gleich meinen obigen Vorschlag.
Ich kanns nämlich auch nicht so recht glauben das die MMF's rund 200x schneller sein sollen.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#46

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 11:30
@negaH:

ja, danke für den hinweis mit dem umständlichen code. ich war auch gerade dabei diesen zu optimieren, wollte mir allerdings vorher
die entsprechenden msdn artikel zur gemüte führen.

P := MapViewOfFile(FMapping, FILE_MAP_READ, 0, 0, 0); wieviel wird hier eigentlich in den speicher gelesen? laut meiner hilfe ist der letzte parameter dwNumberOfBytesToMap ja auf 0.

um das 2gb problem zu beheben müsste ich dwFileOffsetLow u. dwFileOffsetHigh erhöhen.

was ich auch nicht ganz verstehe, ist wo bei folgendem code die erhöhung der akt. lese position stattfindet:

Delphi-Quellcode:
while FSFile1.Position < FSFile1.Size do
begin
 L1 := FSFile1.Read(B1[1], BlockSize);
 L2 := FSFile2.Read(B2[1], BlockSize);
 if L1 <> L2 then
  Exit;
 if not CompareMem(@B1[1], @B2[1], L1) then
  Exit;
end;
edit, hat sich erledigt mit der inkrementierung in obigem code, ist klar.
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#47

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 11:32
Zitat:
Aber 3,44 im Verhältnis zu 700 Sekunden hätte ich weis Gott nicht vermutet, da hätte ich Bigg mit seiner Aussage ebenfalls Recht gegeben. Bist du dir sicher das du auch wirklich die kompletten Dateien verglichen hast ? Schiebe mal ein FSFile1.Position := 0; und FSFile2.Position :=0; mit rein, oder benutze gleich meinen obigen Vorschlag.
Ich kanns nämlich auch nicht so recht glauben das die MMF's rund 200x schneller sein sollen.
kann gut sein, dass der test nicht aussagekräftig ist. siehe meinen vorherigen post.
  Mit Zitat antworten Zitat
Benutzerbild von Sharky
Sharky

Registriert seit: 29. Mai 2002
Ort: Frankfurt
8.252 Beiträge
 
Delphi 2006 Professional
 
#48

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 11:36
Zitat von dahead:
... wo bei folgendem code die erhöhung der akt. lese position stattfindet:
Hai,

.Read setzt doch die Position immer auf das letze gelesene Byte + 1 oder?
Stephan B.
"Lasst den Gänsen ihre Füßchen"
  Mit Zitat antworten Zitat
Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#49

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 11:38
@sharky:

ja, du hast recht. ist mir gerade auch klar geworden als ich da zwei breakpoints auf die entsprechenden read stellen gesetzt habe.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#50

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 11:44
Zitat:
was ich auch nicht ganz verstehe, ist wo bei folgendem code die erhöhung der akt. lese position stattfindet:
Na bei .Read() wird die .Position um +SizeOf(Buffer) erhöht.

Um die MMF's richtig zu nutzen solltest du:

1.) GetFileSize() in einen Int64 speichern, also alle Zähler auf Int64 umbauen
2.) MapViewOfFile() muß mit einen (OffsetLo,OffsetHi) = Int64 arbeiten
3.) MapViewOfFile() sollte bei dwNumberOfBytesToMap mit zb. > 64Kb arbeiten
4.) die innerste Schleife muß also wiederholt mit MapVieOfFile() solche 64Kb Stückchen laden, dann mit CompareMem() vergleichen und wieder freigeben, zumindestens so lange wie sich beide Dateien gleichen

Duch die Verwendung von Happen a >64Kb hast du nun nochmals einen Geschwindigkeitsvorteil. Denn nun bricht deine Laderoutine bei großen Datei die aber unterschiedlich sind viel frühzeitiger ab. Angenommen zwei 1Gb Dateien die sich aber schon in den ersten Bytes unterscheiden. Bei der jetzigen Methode muß das OS 2Gb an daten in den Speicher einlesen, das dauert. Bei der Methode mit 64Kb Stückchen geht das viel schneller. Und die Wahrscheinlichkeit das zwei gleichgroße Dateien unterschiedlich sind ist viel größer als das sie sich gleichen.

Die 64Kb Stückchengröße sollte man jetzt durch Test ermitteln. Es gilt den korrekten Breakeven Point zu finden an dem die Größe der Stückchen im Verhältnis zum zeitlichen Overhead für MapViewOfFile() und UnmapViewOfFile() den schnellsten Vergleich ergibt. D.h. man sollte die Buffergröße inkrementell so lange erhöhen bis sich die größte Performance pro Byte ergibt.
Ich persönlich würde dies dynamisch zur Laufzeit ermitteln. D.h. der Vergleichscode misst sich selber aus und inkremenmtiert successive die Buffergröße bis sich die größte Performance einstellt. Der Vorteil ist ja das dieser Dateivergleich sehr oft pro Session durchgeführt werden muß.

Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 5 von 12   « Erste     345 67     Letzte »    


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 19:20 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