Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Prozedur beschleunigen / Threads? (https://www.delphipraxis.net/139963-prozedur-beschleunigen-threads.html)

Balu der Bär 9. Sep 2009 09:14


Prozedur beschleunigen / Threads?
 
Moin,

eines meiner Projekte tauscht Dateien aus und verändert den Inhalt von anderen Dateien. Das Ganze sieht ungefähr so aus:
Delphi-Quellcode:
GetMD5(datei1);
GetMD5(datei2);
ErsetzeDateiMitAnderer(datei1, datei2); //=Copyfile
Öffne(datei3);
Ersetze(MD5String1 mit MD5String2 in gesamter Datei);//=direktes Schreiben mittels TStream
Schließe(datei3);
Dies Ganze wird circa 15 mal wiederholt, da 15 Dateien getauscht werden müssen und Einträge in datei3 entsprechend geändert werden müssen.

Beim Ersetzen der MD5-Hashes in datei3 wird bitweise vorgegangen, daher dauert dies etwas.

Mein eigentliches Problem ist: Die gesamte Prozedur dauert selbst auf guten Rechnern um die 2 Minuten, eindeutig zu lang.

Jetzt wäre meine Frage wie man dies beschleunigen könnte. Würden Threads etwas bringen? Jedes Mal muss in Datei3 geschrieben werden, es handelt sich hier also nur um eine Datei. Kann ich von 15 Threads aus auf eine Datei zugreifen und diese ändern? Welche anderen Möglichkeiten würde es geben, den Vorgang zu beschleunigen?

Besten Dank

Angel4585 9. Sep 2009 09:17

Re: Prozedur beschleunigen / Threads?
 
Ich würde einen Thread amchen der in die Datei schreibt und x Threads die die anderen Dateien untersuchen.
die x Threads schieben dann die Informationen die dieser eine Threads braucht in eine Liste welche dieser wiederum abarbeitet.

schlecki 9. Sep 2009 09:35

Re: Prozedur beschleunigen / Threads?
 
ev. kann man auch erstmal die 15 Dateien ändern und alles für die Datei3 vormerken und auf einmal erledigen?

himitsu 9. Sep 2009 09:42

Re: Prozedur beschleunigen / Threads?
 
hierbei Threads :shock:
Seid ihr irre?
Gleichzeitiges Schreiben/Lesen auf einem Datenträger (wenn es nicht grad eine SSD ist) würde alles wohl eher noch verschlimmern.

- erstmal schauen was so langsam ist
- wie groß sind die Dateien?
- man kann es höchstens verlagern

z.B.

Code:
Öffne(datei3); > in TMemoryStream laden
Loop:
  GetMD5(datei1);
  GetMD5(datei2);
  ErsetzeDateiMitAnderer(datei1, datei2);
  Ersetze(MD5String1 mit MD5String2 in gesamter Datei);
wiederhole Loop;
Schließe(datei3); > den MemoryStream speichern

das Ersetzen der MD5-Werte könnte man parallel zur Bearbeitung (hasching)
der jeweils Nächsten in einem Thread machen
> der Thread für die Festplatte und der für den RAM (TMemoryStream) würden sich weniger gegenseitig stören


mach ich z.B. in meinem SSF so, da läuft ein Thread durch die Liste und fragt einen anderen Thread nach den MD5s von Dateien (dieser führt eine Art Stack mit allen Dateien, die er bekommt und arbeitet sie nacheinander ab und dann gibt es noch den Hauptthread für die GUI ... parktisch immer nur ein Thread für den Datenträger und ein/mehrere Threads für Berechnungen im RAM)

[edit]
man, hab ich langsam geschrieben ... im Prinzip hat schlecki recht und das ist auch der erstmal einfachste Optimierungsweg

was noch ginge, wäre alle MD5s zu merken und sie am Ende in einem Durchgang zu ersetzen.

und ansonsten halt erstmal schauen was so langsam ist ... wie gesagt, threads sind hier eigentlich nicht wirklich sinnvoll und machen nur mehr arbeit, selbst wenn sie sogestaltet sind, daß sie sich nicht gegenseitig behindern.

taaktaak 9. Sep 2009 09:59

Re: Prozedur beschleunigen / Threads?
 
Zitat:

hierbei Threads
Seid ihr irre?
Gut formuliert!
Genau das richtige Schmankerl für einen lauen Bürotag!
:mrgreen:

Balu der Bär 9. Sep 2009 10:37

Re: Prozedur beschleunigen / Threads?
 
Danke für eure Ideen!

Zitat:

Zitat von schlecki
ev. kann man auch erstmal die 15 Dateien ändern und alles für die Datei3 vormerken und auf einmal erledigen?

Für den Austausch der Dateien brauche ich die MD5-Hashes nicht. Die sind nur zum Verändern der Datei3 notwendig.

Würde es nun wirklich etwas ausmachen wenn ich erst alle Dateien austausche und dann alles nacheinander in Datei3 schreibe? Kommt das nicht aufs Gleiche raus?

Ihr würdet also einem weiteren Thread tendieren, im Hauptthread wird Datei3 verändert und im zweiten Thread die Dateien ausgetauscht?

himitsu 9. Sep 2009 10:52

Re: Prozedur beschleunigen / Threads?
 
Zitat:

Zitat von Balu der Bär
Ihr würdet also einem weiteren Thread tendieren, im Hauptthread wird Datei3 verändert und im zweiten Thread die Dateien ausgetauscht?

neee, ich würde erstmal schauen was so langsam ist und dieses versuchen zu beschleunigen
und dann über alternativen, wie z.B. Threads, nachdenken.

also nochmal ... wie groß sind die Dateien
und wie werden sie derzeit verarbeitet?

Balu der Bär 9. Sep 2009 10:58

Re: Prozedur beschleunigen / Threads?
 
Sorry, glatt überlesen.

Die Dateien die andere ersetzen sind maximal 1 MB groß. Ich kopiere die alten Dateien (als Backup) und kopiere dann die neuen Dateien an die alte Stelle (mittels CopyFile).

Die Datei3, in welche geschrieben wird, ist maximal 100KB groß. Diese lade ich in einen TStream und ersetze Bit für Bit den MD5-Hash der alten Datei mit dem Hash der neuen Datei.

Luckie 9. Sep 2009 11:06

Re: Prozedur beschleunigen / Threads?
 
Bit für Bit? Geht das überhaupt? Aber du weißt doch, wie lang dein Hash ist, dan nkannst du ihn doch in einem Block ersetzen. Warum zeigst du uns nicht endlich mal deinen Code?

Balu der Bär 9. Sep 2009 11:11

Re: Prozedur beschleunigen / Threads?
 
Delphi-Quellcode:
procedure TXYZ.Replace(File1: TStream; oldmd5, newmd5: MD5Digest);
var
  i: Integer;
  pos: Int64;
  pattern: MD5Digest;
begin
  File1.Position := 0;
  while (File1.size - File1.position) >= sizeof(MD5Digest) do
  begin
    pos := File1.Position;
    File1.readbuffer(pattern, sizeof(MD5Digest));
    File1.position := pos + 1;
    if (comparemem(@pattern[0], @oldmd5[0], sizeof(MD5Digest))) then
    begin
      File1.position := pos;
      File1.writeBuffer(newmd5, sizeof(MD5Digest));
      break;
    end;
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:31 Uhr.
Seite 1 von 2  1 2      

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