Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Indizierung von Dateien (https://www.delphipraxis.net/155531-indizierung-von-dateien.html)

-187- 27. Okt 2010 14:57

Indizierung von Dateien
 
Moin,

ich habe mal eine Frage bezüglich Windows 7 und der Indizierung von Dateien.

Mein Programm überprüft ob ein String in einer XML Datei vorkommt. Mit einer Schleife überprüfe ich so 40.000 Dateien. Wenn ich diese Dateien frisch erstelle und dann mein Programm laufen lassen, dauert die Überprüfung 20 Minuten. Wenn das Programm allerdings einmal durch ist und ich erneut eine Suche starte, dann dauert die Überprüfung nur noch 20 Sekunden.

Mein Programm ist sehr simpel und benutzt keine Index Tabelle, daher muss das an der Windows Indizierung liegen. Kann mir das jemand ganauer erklären ?

bYe

chaosben 27. Okt 2010 15:00

AW: Indizierung von Dateien
 
Also wenn du nicht die Routinen der Windows-Suche benutzt, nutzt du die Windows-Indizierung auch nicht.
Warum dein Programm beim 2. Mal so schnell durch ist, kann ich dir nicht sagen. Aber das wird wohl eher an deinem Code als an Windows liegen. :)

Mithrandir 27. Okt 2010 15:02

AW: Indizierung von Dateien
 
Ich glaube nicht, dass das mit dem Indexdienst von Windows zusammenhängt. Ich denke eher, dass hier die Adressen der einzelnen Dateien (ggf. auch die Dateien selbst, wenn sie nicht zu groß sind) im Cache (lies: Arbeitsspeicher) vorgehalten werden.

@chaosben: Möp? :gruebel: Eigentlich ist das doch ne bekannte Eigenart, dass Windows Dateiteile, auf die gerade zugegriffen wurde, im RAM hält...

Daniela.S 27. Okt 2010 15:03

AW: Indizierung von Dateien
 
Deine XML Datei wird bei zweiten Mal im Chache, also im RAM, liegen und somit nicht noch einmal von der Festplatte geladen werden.

Mithrandir 27. Okt 2010 15:09

AW: Indizierung von Dateien
 
Und wenn man das mal schnell überschlägt und 5 kB pro Datei veranschlagt, dann kommt man auf 200 MB, was ja nun nicht wirklich viel ist. Insofern isses wahrscheinlich, dass der ganze Rotz einfach im Arbeitsspeicher bleibt. Irgendwann werden die Bereiche dann wieder zum Überschreiben freigegeben. Wenn du jetzt nochmal dein Programm startest, weiß Windows, dass die Dateien noch im RAM sind und du bekommst n Geschwindigkeitsrausch. :cyclops:

chaosben 27. Okt 2010 15:23

AW: Indizierung von Dateien
 
Ja gut ... ich dachte auch erst an den Cache habe aber nicht nur 5k pro Datei veranschlagt ... egal.

Ja, der Cache könnte es theoretisch sein.

Du könntest das mit diesem Code gegenprüfen.

-187- 27. Okt 2010 18:04

AW: Indizierung von Dateien
 
Hm Okay das ist ja jetzt blöd wenn das jedesmal 20 Minuten dauert.

Hat jemand ne schnellere Lösung 40.000 Dateien zu durchsuchen als diese:

Code:
for i:=0 to MyFiles.Count-1 do
begin
  if Pos('MyString',MyFiles.Strings[i])>0 then do
    do something...
end;

Sir Rufo 27. Okt 2010 18:12

AW: Indizierung von Dateien
 
Zitat:

Zitat von -187-;
Hm Okay das ist ja jetzt blöd wenn das jedesmal 20 Minuten dauert.

Hat jemand ne schnellere Lösung 40.000 Dateien zu durchsuchen als diese:

Code:
for i:=0 to MyFiles.Count-1 do
begin
  if Pos('MyString',MyFiles.Strings[i])>0 then do
    do something...
end;

Ist das der Teil, der so lange braucht? ME fehlt der Teil, wo die Dateien geladen werden

-187- 27. Okt 2010 19:13

AW: Indizierung von Dateien
 
Oops, ja hab ich natürlich vergessen zu erwähnen. Der Code sieht in etwa so aus:

Code:
  XMLSource:=TStringList.Create;
  try
    for i:=0 to IDList.Count-1 do
    begin
      FilePath:=ExtractFilePath(ParamStr(0))+IDList.Strings[i]+'.xml';
      XMLSource.LoadFromFile(FilePath);
      //Hier verarbeite ich den Source
      XMLSource.Clear;
    end;
  finally
    IDList.Free;
    XMLSource.Free;
  end;

Mithrandir 27. Okt 2010 19:48

AW: Indizierung von Dateien
 
*g*

Jetzt fehlt nur noch der Teil, in welchem du nach dem string suchst. :)

Namenloser 27. Okt 2010 20:04

AW: Indizierung von Dateien
 
Zitat:

Zitat von Mithrandir (Beitrag 1058219)
*g*

Jetzt fehlt nur noch der Teil, in welchem du nach dem string suchst. :)

Schau mal in #7 ;)

Mithrandir 27. Okt 2010 20:10

AW: Indizierung von Dateien
 
gnaaaaaaah.... :wall:

rollstuhlfahrer 27. Okt 2010 20:20

AW: Indizierung von Dateien
 
und vor allem fehlt auch noch die Zeile in der die beschreibende Datei geladen wird. Wenn du eine StringList erzeugst, ist sie normalerweise leer. Dann brauchst du darin auch nicht nach Inhalten zu suchen.

Bernhard

-187- 27. Okt 2010 20:47

AW: Indizierung von Dateien
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1058230)
und vor allem fehlt auch noch die Zeile in der die beschreibende Datei geladen wird. Wenn du eine StringList erzeugst, ist sie normalerweise leer. Dann brauchst du darin auch nicht nach Inhalten zu suchen.

Bernhard

Versteh nicht was du mir damit sagen willst ?!

Also hier nochmal der Code in vereinfachter Form:

Code:
var
  XMLSource, IDList: TStringList;
  FoundCount: Integer;
begin
  XMLSource:=TStringList.Create;
  IDList:=TStringList.Create;
  IDList.Text:=Memo1.Text;
  try
    for i:=0 to IDList.Count-1 do
    begin
      FilePath:=ExtractFilePath(ParamStr(0))+IDList.Strings[i]+'.xml';
      XMLSource.LoadFromFile(FilePath);
      if Pos('MyString',XMLSource.Text)>0 then
        Inc(FoundCount);
      XMLSource.Clear;
    end;
  finally
    IDList.Free;
    XMLSource.Free;
  end;
end;

-187- 27. Okt 2010 21:18

AW: Indizierung von Dateien
 
So ich habe es nochmal genauer ausgearbeitet und gemessen:

Ohne Cache: 9:22 min
Mit Cache: 0:01 min

Und hier noch der benutzte Source Code:

Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  StartTime, EndTime: TDateTime;
  XMLSource, IDList: TStringList;
  i, FoundCount: Integer;
  FilePath, FileName: String;
begin
  XMLSource:=TStringList.Create;
  IDList:=TStringList.Create;
  IDList.Text:=Memo1.Text;
  StartTime:=Time;
  try
    for i:=0 to IDList.Count-1 do
    begin
      FileName:=IDList.Strings[i];
      FilePath:=ExtractFilePath(ParamStr(0))+'XML\'+Copy(FileName,Length(FileName)-1,Length(FileName))+'\'+FileName+'.xml';
      if FileExists(FilePath) then
      begin
        XMLSource.LoadFromFile(FilePath);
        if Pos('MyString',XMLSource.Text)>0 then
          Inc(FoundCount);
        XMLSource.Clear;
      end;
    end;
  finally
    IDList.Free;
    XMLSource.Free;
  end;
  EndTime:=Time;
  ShowMessage(IntToStr(FoundCount)+'   Time: '+TimeToStr(EndTime-StartTime));
end;
Was kann man da Speed technisch noch machen ? Also ohne Cache dauert mir das zu lange...

juergen 27. Okt 2010 21:19

AW: Indizierung von Dateien
 
Hallo,

so ganz steig ich auch nicht durch.
Nach dem laden der TStringList (IDList) würde ich in 2 Schleifen arbeiten.
In der 1. Schleife die Datei in XMLSource zusammenbasteln.
Dann in der 2. Schleife das Pos in der IDList anwenden, oder musst du in der XMLSource suchen? In IDList wäre es etwas schneller weil der jeweilige String kleiner ist.

Du rufst im Moment in der Schleife jedesmal XMLSource.LoadFromFile(FilePath) auf und löschst diese auch wieder. Ob das gut ist?
40.000 Datensätze sollten in wenigen Sekunden(?) durch sein, auch beim ersten Mal, aber nur wenn du direkt in der TStringList suchst und die Oberfläche von den Daten trennst.
Wieviel Arbeitsspeicher verbrauchst du mit deinen Daten?

Bummi 27. Okt 2010 21:25

AW: Indizierung von Dateien
 
@-187-
der Code sieht KISS aus, sollte IMHO flott durchlaufen, was für Datenmengen bewegst Du hierbei insgesamt?

-187- 27. Okt 2010 21:25

AW: Indizierung von Dateien
 
Nein, ich muss in XML Source suchen. IDList stellt nur die Dateinamen die ich lade zur Verfügung. Du kannst ja meinen letzten Code nochmal überfliegen dann sollte es klar sein.

Wieviel Arbeitsspeicher brauch mein Programm ? Gute Frage, wie kann ich das genau messen ? *fg*

-187- 27. Okt 2010 21:26

AW: Indizierung von Dateien
 
Zitat:

Zitat von Bummi (Beitrag 1058251)
@-187-
der Code sieht KISS aus, sollte IMHO flott durchlaufen, was für Datenmengen bewegst Du hierbei insgesamt?

40.000 Dateien, der Durchschnitt liegt bei 3-4 kb pro Datei.

Bummi 27. Okt 2010 21:32

AW: Indizierung von Dateien
 
also ca. 160 MB nicht Welt ...
Stringstreams statt Stringlisten für die innere Schleife werden hier auch nicht bringen, wenn es beim zweiten Durchlauf flott läuft.
Du siehst mich ratlos, sorry, flotte Platte, defragmetieren, Virenscanner die üblichen Verdächtigen.

Satty67 27. Okt 2010 21:33

AW: Indizierung von Dateien
 
Denke Speicher ist kein Problem, eher die Zahl der Dateien (40.000 Stk). Wäre das ganze eine Datei mit der gleichen Datenmenge, wären es auch ohne prefetch/cache immer fix erledigt.

Denke selbst mit Verteilung auf Threads wird Windows & AntiVirus beim ersten Zugriff auf eine Datei immer ausbremsen.

Die Quellen gleich von Anfang an anders zu speichern (z.B. in Datenbank) ist keine Option?

juergen 27. Okt 2010 21:34

AW: Indizierung von Dateien
 
Zitat:

Zitat von -187- (Beitrag 1058252)
Wieviel Arbeitsspeicher brauch mein Programm ? Gute Frage, wie kann ich das genau messen ? *fg*

Für den Anfang kannst du ja im Taskmanager nachschauen wieviel Arbeitsspeicher deine Anwendung nutzt.

Was ist mit XMLSource.LoadFromFile(FilePath) und XMLSource.Clear...

-187- 27. Okt 2010 21:37

AW: Indizierung von Dateien
 
Zitat:

Zitat von juergen (Beitrag 1058257)
Was ist mit XMLSource.LoadFromFile(FilePath) und XMLSource.Clear...

Was soll damit sein ?

Zum Arbeitsspeicher..naja so 5000-6000 k, also ganz normal...

Ich dachte eigentlich Anfangs das eine DB Anwendung überdimensioniert wäre. Naja das Programm ist fertig und ich bin nicht so begeistert von der Idee umzurüsten :)

Satty67 27. Okt 2010 21:39

AW: Indizierung von Dateien
 
Zitat:

Zitat von juergen (Beitrag 1058257)
XMLSource.LoadFromFile(FilePath) und XMLSource.Clear...

Beides gleichzeitig ist natürlich unnötig.

Aber denke alleine die Tatsache, dass der zweite Zugriff nur noch <= 1 Sekunde dauert, lässt kaum Hoffnung, dass durch Code-Optimierung viel zu machen ist. Sein Problem sind ja die 10+ Minuten beim ersten Zugriff.

Zitat:

Zitat von -187- (Beitrag 1058258)
Ich dachte eigentlich Anfangs das eine DB Anwendung überdimensioniert wäre. Naja das Programm ist fertig und ich bin nicht so begeistert von der Idee umzurüsten :)

40.000 Dateien = Datensätze wäre zumindest ein Wert, wo man darüber nachdenken könnte. Ist natürlich nicht so leicht zu erweitern, wie eine XML-Datei in Suchordner zu kopieren.

Wenn alles XML ist, evtl. eine einzelne Datei mit je einer Zeile pro XML-Datei (XML braucht ja kein CRLF, Zeile: Dateiname?XML-Code). Aber wenn das gelesen wird, kommt sicher gleich der Aufschrei, dass genau so eine Idee förmlich nach einer DB bettelt.

-187- 27. Okt 2010 21:41

AW: Indizierung von Dateien
 
Gibt es denn ne Möglichkeit den aktuellen Windows Cache zu speichern und bei jedem Neustart wiederherzustellen ;)

juergen 27. Okt 2010 21:52

AW: Indizierung von Dateien
 
Das seh ich erst jetzt: :wall:
40.000 Dateien von Festplatte lesen...

Hier sah das für mich noch ganz anders aus:

Zitat:

Zitat von -187- (Beitrag 1058211)
Oops, ja hab ich natürlich vergessen zu erwähnen. Der Code sieht in etwa so aus:

Code:
var
  XMLSource, IDList: TStringList;
  FoundCount: Integer;
begin
  XMLSource:=TStringList.Create;
  IDList:=TStringList.Create;
  IDList.Text:=Memo1.Text;
  try
    for i:=0 to IDList.Count-1 do
    begin
      FilePath:=ExtractFilePath(ParamStr(0))+IDList.Strings[i]+'.xml';
      XMLSource.LoadFromFile(FilePath);
      if Pos('MyString',XMLSource.Text)>0 then
        Inc(FoundCount);
      XMLSource.Clear;
    end;
  finally
    IDList.Free;
    XMLSource.Free;
  end;
end;

Wo sind deine Daten? Im Memo oder wirklich als Dateien einzulesen?

-187- 27. Okt 2010 21:54

AW: Indizierung von Dateien
 
Die Daten sind in den XML Files und werden jedesmal eingelesen. Im Memo stehen nur die Dateinamen (Ohne Endung) ... ;)

Satty67 27. Okt 2010 22:02

AW: Indizierung von Dateien
 
Zitat:

Zitat von -187- (Beitrag 1058260)
Gibt es denn ne Möglichkeit den aktuellen Windows Cache zu speichern und bei jedem Neustart wiederherzustellen ;)

Per Systemeinstellung... glaube ich nicht Die Größe lässt sich einstellen, ist aber dann nur ein größerer leerer Cache beim Start. Alternativ Suspend-to-disk, statt ausschalten. :stupid:

-187- 27. Okt 2010 22:06

AW: Indizierung von Dateien
 
Ach ich nehm die 10min erstmal so hin... Mir bleibt ja auch nichts anderes überig wenn ich nicht umbauen will :)

Luckie 27. Okt 2010 23:43

AW: Indizierung von Dateien
 
Damit wirst du leben müssen. 40.000 Dateien sind schon ziemlich viel und wenn sie alle nicht sehr groß sind, wird die Festplatte erst mal ordentlich beschäftigt sein, sie alle zusammen zu suchen und zu lesen. Da hilft nur eine gut defragmentierte Festplatte, damit der Lesekopf nicht ständig hin und her springen muss. Aber zu viel würde ich mir davon nicht versprechen. Der Festplattenzugriff ist nun mal der Flaschenhals.

Wenn du die Möglichkeit hast, kannst du die Dateien ja mal auf einen Rechner mit einer SSD Platte (Also diese Festplatten ohne Scheiben, aber mit Flashspeicher.) kopieren und dann noch mal dein Programm drüberlaufen lassen.

chaosben 28. Okt 2010 08:08

AW: Indizierung von Dateien
 
Oder imho noch schneller: Ne RAMDisk

Bummi 28. Okt 2010 08:11

AW: Indizierung von Dateien
 
@chaosben

läuft das Teil inzwischen zuverlässig??
ich hatte vor ca 3 Jahren mal eine Version gekauft die mein System rech instabil gemacht hat.
Eigentlich eine Sache die ins OS gehört wie früher...

-187- 28. Okt 2010 08:19

AW: Indizierung von Dateien
 
Also ich habe nur Scheiben Festplatten vorliegen und werde mir auch nicht extra eine andere kaufen. :D

Code technisch hab ich alles mögliche getan also werd ich erstmal damit leben. Wenn sich das Programm bewiesen hat werde ich es vielleicht auf DB umrüsten... =)

Mithrandir 28. Okt 2010 10:46

AW: Indizierung von Dateien
 
Zitat:

Zitat von chaosben (Beitrag 1058284)
Oder imho noch schneller: Ne RAMDisk

Wobei die Daten von der Festplatte ja auch erstmal in die RAMDisk geladen werden müssen... :stupid:

p80286 28. Okt 2010 11:39

AW: Indizierung von Dateien
 
Mal von der RAMDisk abgesehen, warum die XML-Datei als XML-Datei behandeln, und nicht einfach als Text oder noch simpler als Binäre Datei?
Da kann man sich zumindestens die Datei-Interpretation sparen. Das sind zwar höchstens Zehntelsekunden, aber 40.000 mal ein paar Zehntel ist auch nicht schlecht.

Gruß
K-H

Satty67 28. Okt 2010 11:42

AW: Indizierung von Dateien
 
Sein aktueller Code liegt ja schon unter 1 Sekunde... wird also bei +/- 1 Sekunde + 10 Minuten bei Erstzugriff bleiben.

p80286 28. Okt 2010 14:05

AW: Indizierung von Dateien
 
Soweit ich weiß (was weiß ich schon), ist das Lesen von Platte auch anders, bzw. man hat es selbst in der Hand.

Gruß
K-H

chaosben 28. Okt 2010 19:23

AW: Indizierung von Dateien
 
Zitat:

Zitat von Bummi (Beitrag 1058285)
@chaosben
läuft das Teil inzwischen zuverlässig??

Ja ... ich hatte noch nie Probleme damit ... selbst @work als Temp-Verzeichnis fürn Firebird-Server liefs wunderbar.

-187- 31. Okt 2010 12:10

AW: Indizierung von Dateien
 
Okay, habe nochmal 2 Stunden investiert und meine Anwendung umgebaut. Ich liege jetzt immer so bei 1-2 Sekunden das ist okay bei einer DB Größe von 120 mb und 44000 Datensätzen.

p80286 1. Nov 2010 15:52

AW: Indizierung von Dateien
 
Ähm.. und was hast Du geändert?

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:58 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