Delphi-PRAXiS
Seite 6 von 7   « Erste     456 7      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   String in TStringList finden verschnellern? (https://www.delphipraxis.net/191366-string-tstringlist-finden-verschnellern.html)

Fritzew 9. Jan 2017 14:03

AW: String in TStringList finden verschnellern?
 
Zitat:

Keinerlei Fehler beim Setzen von Sorted True im Nachhinein, selbst wenn Einträge Doppelt vorhanden sind.
Das ist auch richtig so da ja nur sortiert wird beim setzen von sorted.
Irgendwann muss man sich halt entscheiden ob man duplicate will oder nicht.
Wenn ja kann man sorted später setzen, im anderen Fall entweder von Anfang an sorted oder selber prüfen. Dann sind wir wieder am Anfang :-)

p80286 9. Jan 2017 14:03

AW: String in TStringList finden verschnellern?
 
Zitat:

Zitat von a.def (Beitrag 1358479)
Keinerlei Fehler beim Setzen von Sorted True im Nachhinein, selbst wenn Einträge Doppelt vorhanden sind.

Das setzen von Sorted im Nachhinein ist ja auch nicht der "Standardfall". Entweder, Du machst es hinterher
Delphi-Quellcode:
Liste.Sort;
dann hast du alle Daten oder vorher
Delphi-Quellcode:
Liste.Sorted:=true;
.
Und es gibt bestimmt viele Möglichkeiten beides zu kombinieren und möglichst viel Chaos anzurichten.

Gruß
K-H

Uwe Raabe 9. Jan 2017 14:05

AW: String in TStringList finden verschnellern?
 
Zitat:

Zitat von a.def (Beitrag 1358479)
Keinerlei Fehler beim Setzen von Sorted True im Nachhinein, selbst wenn Einträge Doppelt vorhanden sind.

Das
Delphi-Quellcode:
Duplicates
wird auch nur beim Hinzufügen ausgewertet, nicht beim
Delphi-Quellcode:
Sort
. Das Property ist eben keine Garantie für den Inhalt der Stringlist. Es kann insbesondere jederzeit zwischen zwei
Delphi-Quellcode:
Add
-Aufrufen geändert werden.

a.def 9. Jan 2017 14:54

AW: String in TStringList finden verschnellern?
 
Das Sorted setze ich nur im Nachhinein auf True, damit ich Find() benutzen kann.
Ob es doppelte Einträge gibt oder nicht ist unwichtig. Es dürfte aber normalerweise eh keine geben.

haentschman 9. Jan 2017 16:40

AW: String in TStringList finden verschnellern?
 
Liste der Anhänge anzeigen (Anzahl: 5)
Hallöle...:P

Weil keiner Erbarmen hatte des TDictionary mit der TStringList zu vergleichen mache ich das mal... Ich wollte es auch mal wissen. :wink:

Geschwindigkeit:
Das Dictionary ist ist schneller. :thumb:

Vorgaben:
Range: 10000000 Items
TStringList: unsortiert. (die Werte liegen sortiert vor)
Ergebnis:
Bei der TStringList liegen die Zeiten bei ca. 100 - 950 Milisekunden.
Beim TDictionary stabil bei 0 ms. (:gruebel: Ich wollte es gar nicht glauben.)

Natürlich muß man die Zeit berücksichtigen in der die Listen aufgebaut werden. Das stand aber nicht zur Debatte...:thumb:

Jetzt könnt ihr es auseinandernehmen. :thumb:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes, System.UITypes, System.Generics.Collections, System.Generics.Defaults,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TBlubb = class
  strict private
    FItemValue: Integer;
  public
    constructor Create(ItemValue: Integer);
    property ItemValue: Integer read FItemValue write FItemValue;
  end;

  TfmTest = class(TForm)
    btnStringList: TButton;
    btnDictionary: TButton;
    edtCount: TEdit;
    btnGenerate: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnStringListClick(Sender: TObject);
    procedure btnGenerateClick(Sender: TObject);
    procedure btnDictionaryClick(Sender: TObject);
  private
    FDictionary: TObjectDictionary<string, TBlubb>;
    FStringList: TStringList;
    procedure Generate;
    function Count(StartValue: Cardinal): Cardinal;
  public
  end;

var
  fmTest: TfmTest;

implementation

{$R *.dfm}

procedure TfmTest.FormCreate(Sender: TObject);
begin
  FDictionary := TObjectDictionary<string, TBlubb>.Create([doOwnsValues]);
  FStringList := TStringList.Create;
  Randomize;
end;

procedure TfmTest.FormDestroy(Sender: TObject);
begin
  FDictionary.Free;
  FStringList.Free;
end;

procedure TfmTest.Generate;
var
  I: Integer;
  ItemsCount: Integer;
  Value: TBlubb;
begin
  FDictionary.Clear;
  FStringList.Clear;

  ItemsCount := Random(StrToInt(edtCount.Text));
  for I := 0 to ItemsCount - 1 do
  begin
    Value := TBlubb.Create(I);
    FDictionary.Add(IntToStr(I), Value);
    FStringList.AddObject(IntToStr(I), Value);
  end;
  MessageDlg(Format('%d values generiert.', [ItemsCount]), mtInformation, [mbOK], 0);
end;

function TfmTest.Count(StartValue: Cardinal): Cardinal;
begin
  Result := GetTickCount - StartValue;
end;

procedure TfmTest.btnGenerateClick(Sender: TObject);
begin
  Generate;
end;

procedure TfmTest.btnStringListClick(Sender: TObject);
var
  Start: Integer;
  SearchKey: Integer;
  SearchValue: TBlubb;
  ItemPosition: Integer;
begin
  Start := GetTickCount;
  SearchKey := Random(FStringList.Count - 1);
  ItemPosition := FStringList.IndexOf(IntToStr(SearchKey));
  SearchValue := TBlubb(FStringList.Objects[ItemPosition]);
  MessageDlg(Format('TStringList: Zeit in Milisekunden (Item # %s, Value: %d): %d', [IntToStr(SearchKey), SearchValue.ItemValue, Count(Start)]), mtInformation, [mbOK], 0);
end;

procedure TfmTest.btnDictionaryClick(Sender: TObject);
var
  Start: Integer;
  SearchKey: Integer;
  SearchValue: TBlubb;
begin
  Start := GetTickCount;
  SearchKey := Random(FStringList.Count - 1);
  FDictionary.TryGetValue(IntToStr(SearchKey), SearchValue);
  MessageDlg(Format('TDictonary: Zeit in Milisekunden (Item # %s, Value: %d): %d', [IntToStr(SearchKey), SearchValue.ItemValue, Count(Start)]), mtInformation, [mbOK], 0);
end;

{ TBlubb }

constructor TBlubb.Create(ItemValue: Integer);
begin
  inherited Create;
  FItemValue := ItemValue;
end;

end.

mjustin 9. Jan 2017 16:42

AW: String in TStringList finden verschnellern?
 
Zitat:

Zitat von haentschman (Beitrag 1358494)
Weil keiner Erbarmen hatte des TDictionary mit der TStringList zu vergleichen mache ich das mal... Ich wollte es auch mal wissen. :wink:

Danke für den Blick über den Tellerrand. Dass ein TDictionary schneller ist ist leicht erklärt - sobald über den Hashwert die Position des Eintrags berechnet wird, ist es nur noch ein Speicherzugriff (wenn man keine Kollision hat). Wegen des Hash-Zugriffs hat TDictionary eine O(1) lookup performance, so sagt man :)

haentschman 9. Jan 2017 17:01

AW: String in TStringList finden verschnellern?
 
Hallo... :P
Zitat:

O(1) lookup performance
...Bitte um Erklärung für Ü40. Den Begriff kannte ich noch nicht. :P

mjustin 9. Jan 2017 17:14

AW: String in TStringList finden verschnellern?
 
Zitat:

Zitat von haentschman (Beitrag 1358502)
Hallo... :P
Zitat:

O(1) lookup performance
...Bitte um Erklärung für Ü40. Den Begriff kannte ich noch nicht. :P

O(1) bedeutet Zugriff in konstanter Zeit, unabhängig von der Anzahl (der Elemente die durchsucht werden).

Ich kann es zwar auch nicht in drei Worten erklären (ebenfalls Ü40), aber hier es gibt in der Wikipedia diesen Artikel :

https://de.wikipedia.org/wiki/Landau...e_und_Notation

Bei binärer Suche (TStringList zum Beispiel) hat man O (log n), die Zugriffszeit wächst ungefähr um einen konstanten Betrag, wenn sich das Argument verdoppelt.

haentschman 9. Jan 2017 17:23

AW: String in TStringList finden verschnellern?
 
Zitat:

O(1) bedeutet Zugriff in konstanter Zeit
:P
Again what learned. (Loddar) :lol:

mjustin 9. Jan 2017 17:26

AW: String in TStringList finden verschnellern?
 
Zitat:

Zitat von haentschman (Beitrag 1358507)
Zitat:

O(1) bedeutet Zugriff in konstanter Zeit
:P
Again what learned. (Loddar) :lol:

Was andererseits zu der Frage führt: was fangen wir nun mit den eingesparten 100-950 Millisekunden an? :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 Uhr.
Seite 6 von 7   « Erste     456 7      

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