Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Code Optimierung (https://www.delphipraxis.net/32399-code-optimierung.html)

TheReaper 22. Okt 2004 15:31


Code Optimierung
 
Hallo DP!

Ich habe einen Algorithmus geschrieben um Datein in einem angegebenen Verzeichnis und Unterverzeichnissen zu Suchen. Der Code Funktioniert sehr gut, aber wenn es eine hohe Anzahl an dateien ist (>2000) dauert es sehr sehr lange (>10 min bei XP2100+, ATA133 HDD) bis alles durchsucht wurde.

Code:
procedure GetFilesInDirectoryMP3(ADirectory: string; AMask: String; ARekursiv: Boolean);
var
SR: TSearchRec;
Value, M, S : Integer;
begin
if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then
ADirectory:=ADirectory+'\';

if (FindFirst(ADirectory+AMask,faAnyFile-faDirectory,SR)=0) then
begin
repeat
if (SR.Name<>'.') and (SR.Name<>'..') and (SR.Attr<>faDirectory) then

//ID3Tags, speichern ... einfügen

  MP3.Execute(ADirectory+SR.Name);

  if MP3.ID3v2TLEN<>'' then
     begin
     Value := Trunc(strtoint(mp3.ID3v2TLEN) / 1000);
     M := (value mod 3600) div 60;
     S := (value mod 3600) mod 60;
  end else begin
     Value := Trunc(mp3.spielzeit);
     M := (value mod 3600) div 60;
     S := (value mod 3600) mod 60;
  end;

  mp3liste.Artist:='+ '+MP3.ID3v2TPE1;
  mp3liste.Album:=MP3.ID3v2TALB;
  mp3liste.Titel:=MP3.ID3v2TIT2;
  mp3liste.Genre:=mp3.ID3v2TCON;
  mp3liste.Zeit:=Format('%2.2d:%2.2d', [M, S]);
  mp3liste.TrackNr:=MP3.ID3v2TRCK;
  mp3liste.Dateiname:=SR.Name;
  mp3liste.Pfad:=ADirectory;
  write(f3,mp3liste);


until FindNext(SR)<>0;
FindClose(SR);
end;

// Unterverzeichnis durchsuchen
if ARekursiv then
if (FindFirst(ADirectory+'*.*',faDirectory,SR)=0) then
begin
repeat
  if (SR.Name<>'.') and (SR.Name<>'..') then
    GetFilesInDirectoryMP3(ADirectory+SR.Name,AMask,True);
until FindNext(SR)<>0;
FindClose(SR);
end;
end;
Meine Frage: Hat jemand eine Idee wie den Code schneller machen kann?

ibp 22. Okt 2004 16:41

Re: Code Optimierung
 
Delphi-Quellcode:
...

//ID3Tags, speichern ... einfügen
  if (SR.Name<>'.') and (SR.Name<>'..') and (SR.Attr<>faDirectory) then
    MP3.Execute(ADirectory+SR.Name);

  if MP3.ID3v2TLEN<>'' then
     Value := Trunc(strtoint(mp3.ID3v2TLEN) / 1000);
  else
     Value := Trunc(mp3.spielzeit);

  M := (value mod 3600) div 60;
  S := (value mod 3600) mod 60;

  mp3liste.Artist:='+ '+MP3.ID3v2TPE1;
  mp3liste.Album:=MP3.ID3v2TALB;
  mp3liste.Titel:=MP3.ID3v2TIT2;
  mp3liste.Genre:=mp3.ID3v2TCON;
  mp3liste.Zeit:=Format('%2.2d:%2.2d', [M, S]);
  mp3liste.TrackNr:=MP3.ID3v2TRCK;
  mp3liste.Dateiname:=SR.Name;
  mp3liste.Pfad:=ADirectory;
  write(f3,mp3liste);

...
end;


diesen teil solltest du später erledigen,
d.h. estmal alle dateien suchen, die du brauchst, diese in eine stringlist schreiben und dann später verarbeiten, gerade das write wird viel zeit in anspruch nehmen

TheReaper 22. Okt 2004 18:21

Re: Code Optimierung
 
Zitat:

diesen teil solltest du später erledigen,
d.h. estmal alle dateien suchen, die du brauchst, diese in eine stringlist schreiben und dann später verarbeiten, gerade das write wird viel zeit in anspruch nehmen
was hätte das für einen Sinn später alles in ne datei zu schreiben? das wäre dann theroetisch noch langsamer.

statt: datei suchen --> bearbeiten --> Datei speichern --> Nächste Datei
so: datei suchen --> In Stringlist schmeißen --> Nächste Datei --> Stringlist auslesen --> bearbeiten --> Datei Speichern --> Nächste Datei der Stringlist

Die ersten 3 Schritte wären ja schneller aber danach muss ich ein 2. mal jede einzelne Datei öffnen und die Tags auslesen. Oder hab ich das falsch verstanden? :gruebel:

glkgereon 22. Okt 2004 18:58

Re: Code Optimierung
 
naja, aber zb winamp machts ja so:

erstmal nur einlesen...

die tags kommen erst wenn man sie auch abspielt/sie in der playlist sieht
das könntest du auch machen

dann brauch es zwar insgesamt länger, aber der user merkt es nicht...das is der trick

TheReaper 22. Okt 2004 19:16

Re: Code Optimierung
 
Ich kann die daten (ID3Tags) nicht erst in der Playlist auslesen. Dadurch würden andere Dinge nicht mehr funktionieren. Beim erstellen der MP3 Liste muss einiges ausgelesen und gespeichert werden. Das ist mein Problem sonst hätt ich das schon per Playlist im WinAmp oder MediaPlayer Style gemacht.

iaby 22. Okt 2004 19:16

Re: Code Optimierung
 
also ich habs bei meinem player so gemacht:
+ files in liste einfügen
+ anschliessend thread starten, der die ID3 infos ausliest und gleich die liste aktualisiert

hat auch den vorteil, dass der player gleich voll funktionsfähig ist, da der thread alles im hintergrund erledigt (nidriegste Priorität!)
musst nur aufpassen, wenn der thread noch aktualisiert und du an der liste was veränderst (speziell löschen von einträgen)

gruss,
iaby

Christian Seehase 22. Okt 2004 19:17

Re: Code Optimierung
 
Moin TheReaper,

diese Abfrage

Delphi-Quellcode:
SR.Attr<>faDirectory
ist aber gefährlich, denn sobald auch ein anderes Attribut, zusätzlich zum Attribut Directory enthalten ist, ist die Bedingung erfüllt.

Besser ist gezielt das Attribut abzufragen

Delphi-Quellcode:
(SR.Attr and faDirectory) = 0

TheReaper 22. Okt 2004 21:36

Re: Code Optimierung
 
Ich hab mittlerweile rausgefunden warum das so lange dauerte. Beim Auslesen eines Tags von einer bestimmten Datei war eine Schleife die fast Endlos war. Warum? Keine Ahnung :gruebel:. Mit anderen Playern ging das ohne Probs und mit nem Program zum ID3Tags auslesen gabs auch keine Probs. Ich hab den Code etwas optimiert und für alle die es interessiert Hier isser: :-D

Code:
...

var Pfad array of string;

...

procedure GetFilesInDirectoryMP3(ADirectory: string; AMask: String; ARekursiv: Boolean);
var
SR: TSearchRec;
begin
if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then
ADirectory:=ADirectory+'\';
if (FindFirst(ADirectory+AMask,faAnyFile-faDirectory,SR)=0) then
begin
repeat
if (SR.Name<>'.') and (SR.Name<>'..') and ((SR.Attr and faDirectory) = 0) then

  Setlength(Pfad,length(Pfad)+1);
  Pfad[high(Pfad)]:=ADirectory+SR.Name;

until FindNext(SR)<>0;
FindClose(SR);
end;
if ARekursiv then
if (FindFirst(ADirectory+'*.*',faDirectory,SR)=0) then
begin
repeat
if (SR.Name<>'.') and (SR.Name<>'..') then
GetFilesInDirectoryMP3(ADirectory+SR.Name,AMask,True);
until FindNext(SR)<>0;
FindClose(SR);
end;
end;

procedure Tfrm2wnl.BitBtn1Click(Sender: TObject);
var
i:integer;
Value, M, S : Integer;
begin
seek(f3,filesize(f3));
getfilesindirectoryMP3(directorylistbox1.Directory,'*.mp3' ,true);
if high(pfad)>=1 then
frm2wnl.progressbar1.Max:=high(pfad);

for i:=0 to high(pfad) do
begin
if Uppercase(ExtractFileExt(pfad[i]))<>'.MP3' then Continue;

  MP3.Execute(pfad[i]);
  if MP3.ID3v2TLEN<>'' then
     Value := Trunc(strtoint(mp3.ID3v2TLEN) / 1000)
  else
     Value := Trunc(mp3.spielzeit);

  M := (value mod 3600) div 60;
  S := (value mod 3600) mod 60;

  if MP3.ID3v2TPE1<> '' then mp3liste.Artist:='+ '+MP3.ID3v2TPE1   //Das mit dem '+' passt schon. Einfach ignorieren.
  else mp3liste.Artist := '+ Unbekannt';
  if MP3.ID3v2TALB<> '' then mp3liste.Album:=MP3.ID3v2TALB
  else mp3liste.Album := 'Unbekannt';
  if MP3.ID3v2TIT2<> '' then mp3liste.Titel:=MP3.ID3v2TIT2
  else mp3liste.Titel := 'Unbekannt';
  if mp3.ID3v2TCON<> '' then mp3liste.Genre:=mp3.ID3v2TCON
  else mp3liste.Genre := 'Unbekannt';

  mp3liste.Zeit:=Format('%2.2d:%2.2d', [M, S]);

  if MP3.ID3v2TRCK<> '' then mp3liste.TrackNr:=MP3.ID3v2TRCK
  else mp3liste.TrackNr := '00';

  if fileexists (pfad[i]) then
  begin
  mp3liste.Dateiname:=ExtractFileName(Pfad[i]);
  mp3liste.Pfad:=ExtractFilePath(Pfad[i]);
  end;

  write(f3,mp3liste);
  frm2wnl.progressbar1.position:=i;
end;

...

end;
Wenn einer ne Idee hat diesen Code noch besser zu machen dann soll er es bitte nicht für sich behalten. :wink:

punker76 9. Nov 2004 11:00

Re: Code Optimierung
 
Delphi-Quellcode:
if Uppercase(ExtractFileExt(pfad[i]))<>'.MP3' then Continue;
brauchst du eigentlich nicht, da du ja sowieso nach mp3's suchst...

Delphi-Quellcode:
getfilesindirectoryMP3(directorylistbox1.Directory,'*.mp3' ,true);


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