Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Strings vergleichen geht SAULAHM!!! (https://www.delphipraxis.net/37095-strings-vergleichen-geht-saulahm.html)

silentAMD 30. Dez 2004 22:28


Strings vergleichen geht SAULAHM!!!
 
hi,
ich in meinem dateimanager mit unten stehender funktion eine zahl aus, um den passenden imageindex eines objekts in einer dateiliste im listview je nach dateityp herauszubekommen. (also e ist dann der dateiname)


Delphi-Quellcode:
function TFenster.GetImgIndex(e: String): Byte;
var
  i: Integer;
begin
  RESULT := 17;
  i := LastDelimiter('.'+PathDelim+DriveDelim, e);
  if (i > 0) and (e[i] = '.') then begin
    e := LOWERCASE(Copy(e, i+1, MaxInt));
    if (e='exe') then
    RESULT := 6
    else if (e='jpg') or (e='jpeg') or (e='bmp') or (e='gif') or (e='png') then
    RESULT := 7
    else if (e='htm') or (e='html') then
    RESULT := 8
    else if (e='txt') or (e='ini') or (e='inf') or (e='css') then
    RESULT := 9
    else if (e='rar') or (e='zip') or (e='cab') then
    RESULT := 10
    else if (e='mp3') or (e='wav') or (e='ogg') or (e='mid') or (e='wma') then
    RESULT := 11
    else if (e='mpg') or (e='mpeg') or (e='mpe') or (e='wmv') or (e='avi') or (e='asf') or (e='mov') or (e='rm') then
    RESULT := 12
    else if (e='doc') or (e='rtf') or (e='pdf') or (e='ppt') then
    RESULT := 13
    else if (e='hlp') or (e='chm') then
    RESULT := 14
    else if (e='swf') then
    RESULT := 15
    else if (e='lnk') then
    RESULT := 16
  end;
end;

ist es hier angebrachter, einfach den dateityp mit der eigenschaft getimageindex herauszubekommmen (was die scrollgeschwindigkeit beeinträchtigt) oder gleich in der suche (ich weise mit dieser funktion gleich in der suche den imageindex zu, was allerdings das einlesen der dateien verlangsamt).

nun meine frage: wie kann ich die obenstehende funktion "schneller machen" (also geschickterer code)?

Joe24 30. Dez 2004 22:31

Re: Strings vergleichen geht SAULAHM!!!
 
Anstelle der bedingten Verzweigung (if-then-else) würde ich erstmal eine Case-Strucktur wählen.
Sieht dann schon einmal eleganter aus.

upps! e ist ja kein ordinaler Typ. Zu Spät gesehen.

Joe24 30. Dez 2004 22:51

Re: Strings vergleichen geht SAULAHM!!!
 
Das dein Code so langsam ist wird wohl eher an diesem Teil deiner Funktion liegen

Zitat:

Delphi-Quellcode:
...
  i := LastDelimiter('.'+PathDelim+DriveDelim, e);
  if (i > 0) and (e[i] = '.') then begin
    e := LOWERCASE(Copy(e, i+1, MaxInt));
...

den folgenden Teil habe ich 10000000 mal mit einer Schleife aufgerufen, und diese war
nach der Zeitmessung in 4sec durchlaufen.

Zitat:

Delphi-Quellcode:
...
  e := 'lnk';
  RESULT := 17;

 if (e='exe') then
    RESULT := 6
    else if (e='jpg') or (e='jpeg') or (e='bmp') or (e='gif') or (e='png') then
    RESULT := 7
    else if (e='htm') or (e='html') then
    RESULT := 8
    else if (e='txt') or (e='ini') or (e='inf') or (e='css') then
    RESULT := 9
    else if (e='rar') or (e='zip') or (e='cab') then
    RESULT := 10
    else if (e='mp3') or (e='wav') or (e='ogg') or (e='mid') or (e='wma') then
    RESULT := 11
    else if (e='mpg') or (e='mpeg') or (e='mpe') or (e='wmv') or (e='avi') or (e='asf') or (e='mov') or (e='rm') then
    RESULT := 12
    else if (e='doc') or (e='rtf') or (e='pdf') or (e='ppt') then
    RESULT := 13
    else if (e='hlp') or (e='chm') then
    RESULT := 14
    else if (e='swf') then
    RESULT := 15
    else if (e='lnk') then
    RESULT := 16
...


silentAMD 30. Dez 2004 22:58

Re: Strings vergleichen geht SAULAHM!!!
 
hmmm.... ich hab den code einfach von den sources von delphi übernommen und habs so abgeändert, dass nur die datei-endung ohne punkt erscheint... also ich hab "nur" 2166 mhz und bei mir macht die funktioin schon bei ca. 10000 dateien einen größeren unterschied als 4 sekunden!

da wirst du warscheinlich mit deiner übertakteten cpu mit über 3,8 ghz drangegangen sein... :wink:


wenns wirklich am oberen teil hängt: wie soll ich es abändern?

Dax 30. Dez 2004 23:00

Re: Strings vergleichen geht SAULAHM!!!
 
Ganz einfache Idee: Checksumme des Strings berechnen und mit Checksummen der anderen String vergleichen, dann kannst du auch case-of benutzen ;)

Muetze1 30. Dez 2004 23:01

Re: Strings vergleichen geht SAULAHM!!!
 
Moin!

Delphi-Quellcode:
function TFenster.GetImgIndex(Const AFileName: String): Byte;
Type
  TFileAsso = Record
    Ext : String;
    Idx : Integer;
  End;
Const
  coImageIndex : Array[0..38] Of TFileAsso = ( 
    ( Ext: 'exe'; Idx: 6 ),

    ( Ext: 'jpg'; Idx: 7 ),
    ( Ext: 'jpeg'; Idx: 7 ),
    ( Ext: 'bmp'; Idx: 7 ),
    ( Ext: 'gif'; Idx: 7 ),
    ( Ext: 'png'; Idx: 7 ),

    ( Ext: 'htm'; Idx: 8 ),
    ( Ext: 'html'; Idx: 8 ),

    ( Ext: 'txt'; Idx: 9 ),
    ( Ext: 'ini'; Idx: 9 ),
    ( Ext: 'inf'; Idx: 9 ),
    ( Ext: 'css'; Idx: 9 ),

    ( Ext: 'rar'; Idx: 10 ),
    ( Ext: 'zip'; Idx: 10 ),
    ( Ext: 'cab'; Idx: 10 ),
    ( Ext: 'ace'; Idx: 10 ),

    ( Ext: 'mp3'; Idx: 11 ),
    ( Ext: 'wav'; Idx: 11 ),
    ( Ext: 'ogg'; Idx: 11 ),
    ( Ext: 'mid'; Idx: 11 ),
    ( Ext: 'wma'; Idx: 11 ),
    ( Ext: 'rma'; Idx: 11 ),

    ( Ext: 'mpg'; Idx: 12 ),
    ( Ext: 'mpeg'; Idx: 12 ),
    ( Ext: 'mpe'; Idx: 12 ),
    ( Ext: 'wmv'; Idx: 12 ),
    ( Ext: 'avi'; Idx: 12 ),
    ( Ext: 'asf'; Idx: 12 ),
    ( Ext: 'mov'; Idx: 12 ),
    ( Ext: 'rm';  Idx: 12 ),

    ( Ext: 'doc'; Idx: 13 ),
    ( Ext: 'rtf'; Idx: 13 ),
    ( Ext: 'pdf'; Idx: 13 ),
    ( Ext: 'ppt'; Idx: 13 ),
    ( Ext: 'pps'; Idx: 13 ),

    ( Ext: 'hlp'; Idx: 14 ),
    ( Ext: 'chm'; Idx: 14 ),

    ( Ext: 'swf'; Idx: 15 ),

    ( Ext: 'lnk'; Idx: 16 ) );
var
  lExt : String;
  i   : Integer;
begin
  RESULT := 17;

  lExt := Copy(LowerCase(ExtraFileExt(AFileName)), 2, MaxInt);

  If ( Length(lExt) > 0 ) Then // mehr als nur der Punkt
    For i := Low(coImageIndex) To High(coImageIndex) Do
      If ( coImageIndex[i].Ext = lExt ) Then
      Begin
        Result := coImageIndex[i].Idx;
        Break;
      End;
end;
MfG
Muetze1

silentAMD 30. Dez 2004 23:05

Re: Strings vergleichen geht SAULAHM!!!
 
wow danke für die arbeit!!!!! :thumb:
das is ja sowas wie ein array im array oder?

muss gleich mal testen obs schneller geht....


THANX!!!

Muetze1 30. Dez 2004 23:10

Re: Strings vergleichen geht SAULAHM!!!
 
Moin!

Oh - ich sehe gerade das ein Integer etwas überdimensioniert war, es reicht bei dem Type TFileAsso auch ein Byte für den Idx, aber die Optimierung wird es intern eh wieder zum Integer machen...

Zitat:

Zitat von silentAMD
das is ja sowas wie ein array im array oder?

Nö, eigentlich nur ein konstantes Array aus Records.

Zitat:

Zitat von silentAMD
muss gleich mal testen obs schneller geht....

Jo, würde mich mal interessieren...

MfG
Muetze1

Christian Seehase 31. Dez 2004 00:15

Re: Strings vergleichen geht SAULAHM!!!
 
Moin silentAMD,

um mal die Idee von Dax aufzugreifen, mal etwas ähnliches:
Funktioniert allerdings nur bei Erweiterungen mit ein bis vier Zeichen.

Ich hoffe es ist ersichtlich wie sich die Zahlen ergeben.

Delphi-Quellcode:
function Ext2ID(const AsFilepath : string) : integer;

type
  TcsExtToDW = packed record
    case byte of
      0 : (sExt : string[4]);
      1 : (bDummy : byte;
           dwExt : DWORD);
  end;

var
  etdWork : TcsExtToDW;

begin
  Result       := -1;
  etdWork.dwExt := 0;
  etdWork.sExt := AnsiLowerCase(copy(ExtractFileExt(AsFilePath),2,4));
  case etdWork.dwExt of
    $00657865 : Result := 6; // exe
    $0067706A, // jpg
    $6765706A, // jpeg
    $00706D62, // bmp
    $00666967, // gif
    $00676E70 : Result := 7; // png
    $006D7468, // htm
    $6C6D7468 : Result := 8; // html
    $00747874, // txt
    $00696E69, // ini
    $00666E69, // inf
    $00737363 : Result := 9; // css
    $00726172, // rar
    $0070697A, // zip
    $00626163, // cab
    $00656361 : Result := 10; // ace
    $0033706D, // mp3
    $00766177, // wav
    $0067676F, // ogg
    $0064696D, // mid
    $00616D77, // wma
    $00616D72 : Result := 11; // rma
    $0067706D, // mpg
    $6765706D, // mpeg
    $0065706D, // mpe
    $00766D77, // wmv
    $00697661, // avi
    $00667361, // asf
    $00766F6D, // mov
    $00006D72 : Result := 12; // rm
    $00636F64, // doc
    $00667472, // rtf
    $00666470, // pdf
    $00747070, // ppt
    $00737070 : Result := 13; // pps
    $00706C68, // hlp
    $006D6863 : Result := 14; // chm
    $00667773 : Result := 15; // swf
    $006B6E6C : Result := 16// lnk
  end;
end;

silentAMD 31. Dez 2004 12:09

Re: Strings vergleichen geht SAULAHM!!!
 
hi,

die möglichkeit von Muetze1 ist leider so um die 60% langsamer (bei 1000000 durchläufen)...
hier die wertetabelle:


meine möglichkeit: ~ 0,835528537844894
Muetze1's: ~ 1,40521434986849
Christian Seehase's: ~ 0,802533841591599

und die 4. aus allen: ~ 0,440150074939692


hier ist sie (sogar mit mehr dateitypen):

Delphi-Quellcode:
function GetImgIndex(const lExt: string) : Byte;

type
  TcsExtToDW = packed record
    case byte of
      0 : (sExt : string[4]);
      1 : (bDummy : byte;
           dwExt : DWORD);
  end;

var
  etdWork : TcsExtToDW;
  i: Integer;

begin
  RESULT := 17;
  etdWork.dwExt := 0;
  i := LastDelimiter('.'+PathDelim+DriveDelim, lExt);
  if (i > 0) and (lExt[i] = '.') then begin
    etdWork.sExt := LOWERCASE(Copy(lExt, i+1, MaxInt));


  case etdWork.dwExt of
    $00657865 : Result := 6; // exe
    $0067706A, // jpg
    $6765706A, // jpeg
    $00706D62, // bmp
    $00666967, // gif
    $00676E70 : Result := 7; // png
    $006D7468, // htm
    $6C6D7468 : Result := 8; // html
    $00747874, // txt
    $00696E69, // ini
    $00666E69, // inf
    $00737363 : Result := 9; // css
    $00726172, // rar
    $0070697A, // zip
    $00626163, // cab
    $00656361 : Result := 10; // ace
    $0033706D, // mp3
    $00766177, // wav
    $0067676F, // ogg
    $0064696D, // mid
    $00616D77, // wma
    $00616D72 : Result := 11; // rma
    $0067706D, // mpg
    $6765706D, // mpeg
    $0065706D, // mpe
    $00766D77, // wmv
    $00697661, // avi
    $00667361, // asf
    $00766F6D, // mov
    $00006D72 : Result := 12; // rm
    $00636F64, // doc
    $00667472, // rtf
    $00666470, // pdf
    $00747070, // ppt
    $00737070 : Result := 13; // pps
    $00706C68, // hlp
    $006D6863 : Result := 14; // chm
    $00667773 : Result := 15; // swf
    $006B6E6C : Result := 16// lnk
  end;
end;
end;

bis dateitypen kommen, die mehr als 4 zeichen haben, oder es noch eine schnellere möglichkeit gibt, nehme ich die lösung!! :wink:

danke!!!


edit: noch ne frage - WARUM IST ANSILOWERCASE LANGSAMER ALS LOWERCASE????

edit2: und wie macht das der explorer???

sakura 31. Dez 2004 12:25

Re: Strings vergleichen geht SAULAHM!!!
 
Zitat:

Zitat von silentAMD
edit: noch ne frage - WARUM IST ANSILOWERCASE LANGSAMER ALS LOWERCASE????

AnsiLowerCase ist abhängig vom jeweiligen Zeichensatz und beachtet zB auch Umlaute, LowerCase kümmert sich nur um 'A'...'Z'.

Zitat:

Zitat von silentAMD
edit2: und wie macht das der explorer???

Der braucht teilweise ewig bei Verzeichnissen mit über 2500 Dateien :(

...:cat:...

silentAMD 31. Dez 2004 12:34

Re: Strings vergleichen geht SAULAHM!!!
 
Zitat:

Zitat von sakura
Zitat:

Zitat von silentAMD
edit2: und wie macht das der explorer???

Der braucht teilweise ewig bei Verzeichnissen mit über 2500 Dateien :(

...:cat:...

also bei mir braucht das nämlich net so lang... wahrscheinlich hast du ein verzeichnis von 2500 exe dateien und hast ein virenprogramm wie antivir drauf, das den vorgang derb verlangsamt...
und genau deswegen (weil ich immer ein antivirenprog drauf hab) hab ich mir einfach nen filemanager zusammengebastelt, der nicht die windowssymbole ausliest.

sakura 31. Dez 2004 12:36

Re: Strings vergleichen geht SAULAHM!!!
 
Zitat:

Zitat von silentAMD
also bei mir braucht das nämlich net so lang... wahrscheinlich hast du ein verzeichnis von 2500 exe dateien und hast ein virenprogramm wie antivir drauf, das den vorgang derb verlangsamt...

Nein, ganz bestimmt nicht :roll: Es sind DAT-Dateien, keine Virenscanner installiert. Es können auch mehr (so 25000) sein, dann dauert es nur noch viiiieeel länger. :?

Aber mal ehrlich, bei 1.000.000 Durchläufen sind selbst 2 Sekunden kein Problem. Wenn man soviel in einem Verzeichnis hat, dann dauert es eh Stunden, bis man die richtige Datei gefunden hat...

...:cat:...

Sprint 31. Dez 2004 14:12

Re: Strings vergleichen geht SAULAHM!!!
 
Zitat:

Zitat von silentAMD
die möglichkeit von Muetze1 ist leider so um die 60% langsamer

Dein Problem muss irgendwo anders liegen. Bei 1.000.000 Aufrufen brauche ich 961 Millisekunden auf einem 2.6 GHz Rechner.


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