AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi ListFiles mit FindFirst beschleunigen
Thema durchsuchen
Ansicht
Themen-Optionen

ListFiles mit FindFirst beschleunigen

Ein Thema von Moony · begonnen am 12. Jan 2010 · letzter Beitrag vom 13. Jan 2010
Antwort Antwort
Seite 1 von 2  1 2      
Moony

Registriert seit: 29. Jul 2003
Ort: Essen
454 Beiträge
 
Delphi 2010 Professional
 
#1

ListFiles mit FindFirst beschleunigen

  Alt 12. Jan 2010, 16:01
Hallo zusammen,

ich habe bei meiner Applikation mittlerweile festgestellt, dass die Routine zum Auflisten bestimmter Dateien in einem Verzeichnis bei knapp 3500 Dateien ca. 15 Sekunden dauert. Ich suche mit folgender Routine das Verzeichnis ab:

Delphi-Quellcode:
procedure ListFiles(Path, Ext: string; FileList: TStringList; Attr: integer);
var
  SR : TSearchRec;
begin
  if Length(Path) > 0 then
    Path := IncludeTrailingBackslash(Path);

  if FindFirst(Path + Ext, faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
         if (fmPhoto.ImageSet.CheckAttr) and (not fmPhoto.DoRefreshAll) then
          if (SR.Attr and Attr) = 0 then
            Continue;

         if UpperCase(ExtractFileExt(SR.Name)) = UpperCase(ExtractFileExt(Ext)) then
          FileList.Add(SR.Name);
      end;
    until FindNext(SR) <> 0;
    SysUtils.FindClose(SR);
  end;
end;
Sind die Kriterien erfüllt worden, wird dann außerhalb dieser Routine weiter mit den einzelnen Dateien gearbeitet.

Wie kann man also diese Routine optimieren bzw. beschleunigen?

Danke & Gruß, Moony
Ich weiß, daß ich nichts weiß! Sokrates
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: ListFiles mit FindFirst beschleunigen

  Alt 12. Jan 2010, 16:05
FindFirst ist von Haus aus langsam. (einzige Lösung wäre die MFT direkt auszulesen, aber das ist nicht unbedingt so einfach)

Was du aber machen kannst (es kommt darauf an, was sich hinter der Stringliste versteckt), wäre deren Updaten per Delphi-Referenz durchsuchenBeginUpdate abzuschalten.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.202 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: ListFiles mit FindFirst beschleunigen

  Alt 12. Jan 2010, 16:06
Z.B. UpperCase(ExtractFileExt(Ext)) nur einmal am Anfang der Funktion machen.

Und da wir nicht wissen was (fmPhoto.ImageSet.CheckAttr) and (not fmPhoto.DoRefreshAll) ist evtl. das die Bremse (Profiler würde helfen)
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Moony

Registriert seit: 29. Jul 2003
Ort: Essen
454 Beiträge
 
Delphi 2010 Professional
 
#4

Re: ListFiles mit FindFirst beschleunigen

  Alt 12. Jan 2010, 16:37
Oh, sorry.

Das
(fmPhoto.ImageSet.CheckAttr) and (not fmPhoto.DoRefreshAll) sind Boolean-Variablen einfach nur um zu prüfen ob ich alle Dateien mit der Endung nehmen soll oder nur die mit der angegebenem Attribut.

Das Uppercase nur einmal aufzurufen hat keine Verbesserung gebracht.

@himitsu: Die Stringliste wird leer übergeben und in dieser Routine ggf. gefüllt, damit ich weiter mit den benötigten Dateien arbeiten kann. Wie kann ich das denn mit MFT lösen bzw. in wie weit hilft mir BeginUpdate weiter?

Gruß
Ich weiß, daß ich nichts weiß! Sokrates
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: ListFiles mit FindFirst beschleunigen

  Alt 12. Jan 2010, 17:14
Hallo,

wo suchst du die Dateien? Lokal auf der Festplatte oder im Netzwerk?
Welches Betriebssystem verwendest du?
Wenn du mehrfach im selben Verzeichnis suchst, ändert sich die Zeit?
Befinden sich andere Dateien in dem Verzeichnis, die die Suchkriterien nicht erfüllen (z.B. andere Dateiendung)

Das sind so die Kriterien, nach den ich diese Suchalgorithmen angepackt habe.

Aber es ist tatsächlich so, dass es Situationen gibt, bei denen man nicht schneller werden kannst. Selbst MS versucht dieses Problem an zu gehen durch Indizierung der Dateien oder andere File-Systeme die eine Suche ermöglichen.

Aber das hilft dir ja erstmal nicht weiter.

Greez, Chris
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Moony

Registriert seit: 29. Jul 2003
Ort: Essen
454 Beiträge
 
Delphi 2010 Professional
 
#6

Re: ListFiles mit FindFirst beschleunigen

  Alt 13. Jan 2010, 08:33
Also, die Dateisuche findet fast immer über ein lokales Netzwerk statt. In den Verzeichnissen sind fast immer nur die Dateien drin, welche die gesuchte Endung besitzen, ist aber keine Sicherheit dass es so ist. Es sind ebenfalls Dateien im Verzeichnis, welche die Suchkriterien nicht erfüllen. Es kommt also auch mal vor, dass ein Verzeichnis durchlaufen wird, aber keine zutreffende Datei gefunden wird.
Ich weiß, daß ich nichts weiß! Sokrates
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: ListFiles mit FindFirst beschleunigen

  Alt 13. Jan 2010, 09:17
Hallo Moony,

Über das Netzwerk ist es tatsächlich so, dass die Zeiten deutlich länger sind als auf Lokalen Festplatten des Rechners.

Deinen Algo würde ich erstmal so anpassen wie auch schon von anderen vorgeschlagen:

Delphi-Quellcode:
procedure ListFiles(Path, Ext: string; FileList: TStrings; Attr: integer);
var
  SR : TSearchRec;
  CheckAttrAndNotRefreshAll : Boolean; // neu
begin
  if Length(Path) > 0 then
    Path := IncludeTrailingBackslash(Path);

  //Ext := UpperCase(Ext); // neu
  CheckAttrAndNotRefreshAll := (fmPhoto.ImageSet.CheckAttr) and (not fmPhoto.DoRefreshAll); // neu

  if FindFirst(Path + '*' + Ext, faAnyFile, SR) = 0 then // Stern eingefügt
  begin
    FileList.BeginUpdate;
    try
      repeat
        if (SR.Attr and faDirectory) = 0 then
        begin
           if CheckAttrAndNotRefreshAll then
           begin
             if (SR.Attr and Attr) = 0 then
               Continue;
           end;

           // Brauchst du das Hier wirklich?
           //if UpperCase(ExtractFileExt(SR.Name)) = Ext then
           //begin
             FileList.Add(SR.Name);
           //end;
        end;
      until FindNext(SR) <> 0;
    finally
      FileList.Endupdate;
    end;
    SysUtils.FindClose(SR);
  end;
end;
Wobei ich nicht ganz verstehe, wie du die MEthode aufrufst. Bei mir würde meine Version so aussehen:
Listfiles('X:\TestVieleDateien', '.jpg', ListBox1.Items, 0); Somit wird auch der Vergleich auf die Variable Ext unnötig. Oder hab ich das jetzt was falsch verstanden?

Greez, Chris

[EDIT]Quelltext angepasst wegen Beitrag #9, #11, #13. Danke DeddyH und himitsu[/EDIT]
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: ListFiles mit FindFirst beschleunigen

  Alt 13. Jan 2010, 09:34
MFT (MasterFileTable) ist 'ne Kontrollstruktur innerhalb einer NTFS-Partition ... kann man also nur nutzen, wenn man direkten Zugriff auf dieses Laufwerk hätte ... also im Netzwerk geht sowas nicht.

Wenn noch andere Dateien im Verzeichnis vorhanden sind, neben jenen, welche deiner gesuchten "Dateierweiterung" (EXT), dann könnte es schon was bringen, wenn man nicht erstmal alles sucht und danach filtert.

Die einzige Möglichkeit, welche danach noch eine Beschleunigung bringen würde, wäre das Verzeichnis lokal auszulesen und sich die Liste komplett über's Netzwerk zu schicken.
Also ein Programm auf der anderen Netzwerkseite, welche das direkt ausließt und alles zusammen in einem Datenstrom zu deinem Programm schickt.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#9

Re: ListFiles mit FindFirst beschleunigen

  Alt 13. Jan 2010, 09:50
Bissel OT: Ich frage mich die ganze Zeit, ob diese Zeile wirklich richtig ist:
Zitat:
if (SR.Attr <> faDirectory) then
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

Re: ListFiles mit FindFirst beschleunigen

  Alt 13. Jan 2010, 09:53
Zitat von DeddyH:
Bissel OT: Ich frage mich die ganze Zeit, ob diese Zeile wirklich richtig ist:
Zitat:
if (SR.Attr <> faDirectory) then
Es scheint zu funktionieren, aber besser wäre sicher
if (SR.Attr and faDirectory) <> faDirectory then Da stimme ich dir zu.

Greez, Chris
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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