Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Gibt es einen schnelleren Stringvergleich als if S1 = S2 (https://www.delphipraxis.net/170407-gibt-es-einen-schnelleren-stringvergleich-als-if-s1-%3D-s2.html)

Bjoerk 16. Sep 2012 11:05

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Nein ich denke eher nur dann. Beispiel (hier schlägt der Vergleich fehl):

Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  PString = ^TString;
  TString = string[80];

  TTest = class(TList)
  public
    procedure AddItem(const Value: TString);
    procedure DelItem(Index: integer);
    function CompareItems(const Index1, Index2: integer): boolean;
    destructor Destroy; override;
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TTest.AddItem(const Value: TString);
var
  P: PString;
begin
  New(P);
  P^:= Value;
  Add(P);
end;

procedure TTest.DelItem(Index: integer);
var
  P: PString;
begin
  P:= Items[Index];
  Dispose(P);
  Delete(Index);
end;

destructor TTest.Destroy;
begin
  while Count > 0 do
    DelItem(Count - 1);
  inherited Destroy;
end;

function TTest.CompareItems(const Index1, Index2: integer): boolean;
begin
  Result:= CompareMem(Items[Index1], Items[Index2], SizeOf(TString));
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  Test: TTest;
begin
  Test:= TTest.Create;
  try
    Test.AddItem('TestItem');
    Test.AddItem('TestItem');
    if Test.CompareItems(0, 1) then ShowMessage('CompareItems');
  finally
    Test.Free;
  end;
end;

end.

himitsu 16. Sep 2012 14:27

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Gut, das mit den "identischen" String-Instanzen hab ich mal mit in den Code aufgenommen.

CompareMem wurde auch schon optiiert (hoffe ich), z.B. im FastMM wurden derart optimierte Vergleichs-/Kopiercodes integriert, welche bei kleinen Speicherblöcken optimierte Codes verwenden, die keine Schleifen und dafür teilweise MMX-Register verwenden.

Zitat:

Zitat von Bjoerk (Beitrag 1183143)
Nein ich denke eher nur dann. Beispiel (hier schlägt der Vergleich fehl):

Du mußt natürluch auch wissen was du vergleichst. :warn:

Meine Funktion war die Vorgehensweise bei LongStrings (AnsiString, wideString, UnicodeString).

Doch ein ShortString verfügt über ein anderes Speichermanagent.
Die Delphiimplementation dieses Vergleichs beachtet deswegen die Größenangabe ersten Byte (Index 0) und vergleicht NUR die reinen Stringdaten, denn hinter dem String sind die Daten zufällig/unbestimmt.

Delphi-Quellcode:
'abc' = 'abc'
im Delphicode und mit einem String[6] sieht eventuell so aus
Delphi-Quellcode:
#3'abc'#x#x#x = #3'abc'#x#y#z
(Llngenbyte + Text + KEINE #0 + Sonstewas).

Bjoerk 16. Sep 2012 15:47

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Schlägt auch bei Ansistrings fehl. Anyway. Daß Strings in Delphi kompliziert sind, ist ja eigentlich bekannt. Ich bin hier jedoch der falsche Gesprächspartner. Ich weiß noch nicht mal, was eine Referenzzählung ist. :oops:

himitsu 16. Sep 2012 17:09

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Ein String oder auch ein Interface, bzw. dessen Variable, ist ein "Zeiger".

Mehrere Zeiger können auf den selben "Text" zeigen.

In der Referenzzählung wird mitgezählt wieviele Variablen das sind.

Beim Interface wird dann nach der letzen freigegebenen Referenz meistens das Objekt im Interface freigegeben, denn wenn keiner mehr drauf zeigt, dann wird es nicht mehr benötigt und kann weg.
Beim String ist es genauso. Außer das bei Schreibzugriffen vorher noch geprüft wird, ob diese Variable der Einzige Besitzer ist und wenn nicht, dann wird eine Kopie angelegt und diese verändert, damit sich der Inhalt der anderen variablen nicht verändert.

sx2008 17. Sep 2012 02:34

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Zitat:

Zitat von Bjoerk (Beitrag 1183170)
Schlägt auch bei Ansistrings fehl. Anyway. Daß Strings in Delphi kompliziert sind, ist ja eigentlich bekannt.

Nun, wenn du zwei Strings Short-, Ansi- oder Widestrings ganz normal mit stinknormalem Pascalcode vergleichst dann bekommst du a.) einen funktionieren Code und b.) eine Geschwindigkeit die schwer zu schlagen ist.
Delphi-Quellcode:
function TTest.CompareItems(const Index1, Index2: integer): boolean;
begin
  Result:= CompareStr(Items[Index1], Items[Index2]);
end;
Strings in Delphi sind nicht kompliziert sondern ziemlich effizient und sicher.
Sie sind keine vollwertigen Objekte (wie z.B. die Klasse CString in C++) und andererseits auch nicht Speicherblöcke festgelegter max. Länge wie in der Sprache C.

Bjoerk 17. Sep 2012 08:08

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Abgesehen davon, daß CompareStr zwei Strings statt 2 Pointer als Parameter hat, kann es wie in #7 bereits ausgeführt, nie schneller sein als der direkte Vergleich. Und in #21 ging es darum, daß CompareMem nicht ohne weiteres auf Strings angewendet werden kann.

p80286 17. Sep 2012 09:59

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
mal ganz vorsichtig gefragt, Zu den Zeiten als ein Prozessorregister noch 16Bit breit war, wurden immer 2Byte auf einmal geladen und verglichen, ist das bei den "neueren" Versionen schon eingebaut (32/64 Bit)?

Gruß
K-H

himitsu 17. Sep 2012 12:00

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2
 
Zitat:

Zitat von p80286 (Beitrag 1183243)
ist das bei den "neueren" Versionen schon eingebaut (32/64 Bit)?

Ja :stupid:

Darum ist es auch besser Mehereres gleichzeitig zu vergleichen.

Die von mir genannten Funktionen machen es so:
- erstmal in kleinen Schritten (charweise) solange, bis der Speicher ausgerichtet ist
- dann in großen Schritten (Register/MMX-Register)
- und den Rest wieder Klein

Ob man für die Großen Schleifen braucht kommt drauf an.
- für kleinere definierte Sachen kann man einfach mehrere Varianten ohne Schleifen implementieren, wie z.B. bei 16 Byte einfach 2x 8-Byte-MMX-Register
- für Größeres ja


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:25 Uhr.
Seite 3 von 3     123   

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