AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt haben

Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt haben

Ein Thema von CodeX · begonnen am 23. Feb 2017 · letzter Beitrag vom 28. Feb 2017
Antwort Antwort
nahpets
(Gast)

n/a Beiträge
 
#1

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 23. Feb 2017, 17:55
Streng genommen sind sie also nicht wirklich gleich, sondern die Inhalte werden, sofern sie nur bestimmte Abweichungen enthalten, als gleich betrachtet?

Mir fiele da nur sowas in der Art ein:
Delphi-Quellcode:
function TesteListen(sl1, sl2 : TStringList) : Boolean;
var
         i : Integer;
begin
  Result := sl1.Count = sl2.Count;
  if not Result then exit;
  i := 0;
  repeat
    Result := TestString(sl1[i]) = TestString(sl2[i]);
    inc(i);
  until not Result or (i >= sl1.Count);
end;
TestString sei hierbei eine Funktion, die die Delimiter u. ä. Zeichen eleminiert oder vereinheitlicht, entsprechend den Anforderungen. Könnte also z. B. sowas sein:
Delphi-Quellcode:
function TestString(s : String) : String;
begin
  // " und ; ersatzlos "streichen".
  Result := AnsiReplaceText(AnsiReplaceText(s,'"',''),';',',');
  // Oder: Delimiter ";" wird zu ','
  Result := AnsiReplaceText(s,'";"','','');
end;
Eventuell könnte man diese Änderungen aber auch bereits auf sl1.Text bzw. sl2.Text machen und dann nur noch TesteListen aufrufen, ohne dass dort noch Funktionen aufgerufen werden müssen.

Kannst Du im StringList.Text bereits alle Delimiter ... vereinheitlichen, könnte nachfolgen ein MD5-Checksummenvergleich eventuell schneller werden.

Oder wenn Du die Delimiter vereinheitlichen kannst, dürfte anschließend ein if Stringliste1.Text = Stringliste2.Text then ... für den Vergleich ausreichen.
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#2

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 23. Feb 2017, 19:34
Streng genommen sind sie also nicht wirklich gleich, sondern die Inhalte werden, sofern sie nur bestimmte Abweichungen enthalten, als gleich betrachtet?
Hm, wahrscheinlich habe ich mich nicht eindeutig ausgedrückt...
Ich wollte nur darauf hinaus, dass es mir ausschließlich um die Strings in der Liste geht und nicht um sonstige Eigenschaften. Wenn ich also eine StringListe kopiere und in der Kopie die Eigenschaft Delimiter oder QuoteChar ändere, dann hat sich am Inhalt ja nichts geändert und die beiden Listen wären immer noch als gleich zu betrachten. Ich wollte damit nur anmerken, dass eine Lösung mit Speichervergleich wie CompareMem o.ä. vielleicht nicht die korrekteste Lösung wäre.

Also dann besser durch alle Elemente durchgehen und diese einzeln vergleichen als alles per Strings.Text zusammenzusetzen und nur einen Vergleich durchzuführen?
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#3

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 23. Feb 2017, 20:50
Also dann würd' ich es so versuchen:
Delphi-Quellcode:
function TesteListen(sl1, sl2 : TStringList) : Boolean;
var
         i : Integer;
begin
  Result := sl1.Count = sl2.Count;
  if not Result then exit;
  i := 0;
  repeat
    Result := sl1[i] = sl2[i];
    inc(i);
  until not Result or (i >= sl1.Count);
end;
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.520 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 24. Feb 2017, 09:16
Ich bin auch der Meinung dass ein durchgehen durch die Liste wesentlich schneller ist als Text oder ähnliches zu verwenden. Statt eine repeat würde ich eher einer for Schleife nehmen. Das dann zum Beispiel so (ungetetet)

Delphi-Quellcode:
function TesteListen(sl1, sl2 : TStringList) : Boolean;
var
  i : Integer;
begin
  Result := False;
  if sl1.Count <> sl2.Count
  then Exit;
  for i := sl1.Count - 1 do
  begin
    if sl1[i] <> sl2[i]
    then Exit
  end;
  Result := True;
end;
Falls so ein Vergleich öfters vorkommt und sich die Daten nicht ständig ändern könnte man auch noch über Hashes nachdenken.

Geändert von freimatz (24. Feb 2017 um 09:39 Uhr)
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#5

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 24. Feb 2017, 10:43
Oder eine While-Schleife
Delphi-Quellcode:
var
  i: Integer;
begin
  Result := sl1.Count = sl2.Count;
  i := 0;
  while Result and (i < sl1.Count) do
  begin
    Result := sl1[i] = sl2[i];
    Inc(i);
  end;
end;
Solange niemand einen performanteren Gegenvorschlag zu einer Schleife hat, mache ich das gerne so.
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.520 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 28. Feb 2017, 09:44
Ja genau. Die Möglichkeit ist die schnellste.
...
Solange niemand einen performanteren Gegenvorschlag zu einer Schleife hat, ...
Dazu müsstest du erst mehr Hintergrundinformationen liefern.
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#7

AW: Performanteste Möglichkeit zur Prüfung ob zwei StringListen den gleichen Inhalt h

  Alt 28. Feb 2017, 10:29
Du solltest vielleicht mal ausrechnen, wie schnell du aktuell bist.
Also du musst ja beide Listen komplett aud dem RAM in die CPU schaufeln, das heißt irgendwann kommst du da an das Limit von der Geschwindigkeit des RAM.
Wenn die Lösung aus #9 da in die Nähe kommt, ist da eigentlich nicht viel zu verbessern.

Falls sie es nicht tut, und es noch schneller gehe soll, müsstest du wohl auf assembler gehen und mit SSE-Anweisungen mehrere Bytes auf einmal vergleichen.

Alternativ könntest du probieren, ein paar Durchläufe der Schleife zusammenzufassen. In etwa so:
Delphi-Quellcode:
var
  i: Integer;
  maxi: Integer;
begin
  Result := sl1.Count = sl2.Count;
  i := 0;
  maxi = (sl1.Count div 4) * 4;

  while Result and (i < maxi) do
  begin
    Result := Result or (sl1[i+0] = sl2[i+0]);
    Result := Result or (sl1[i+1] = sl2[i+1]);
    Result := Result or (sl1[i+2] = sl2[i+2]);
    Result := Result or (sl1[i+3] = sl2[i+3]);
    Inc(i, 4);
  end;
  
  while Result and (i < sl1.Count) do
  begin
    Result := sl1[i] = sl2[i];
    Inc(i);
  end;
end;
Keine Ahnung, ob der Compiler soetwas inzwischen automatisch macht, aber das könnte noch ein paar Prozent Unterschied bringen.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 03:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz