Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

13.04.2014, 13:32

String-Vergleich: Der schnellste Weg

Ich habe mir heute einfach einmal spaßeshalber überlegt, was wohl der schnellste Weg ist, in C++ (mit oder ohne STL) zwei Zeichenketten zu vergleichen.
Erstmal gäbe es ja std::string und char[]. Danach könnte man noch weiter abstrahieren: STL ==, strcmp, memcmp, ...
Der Sinn dahinter ist eigentlich erstmal keiner, es ist reine Interesse. Aktuelle sehen meine std::string-Vergleiche immer so aus:

C-/C++-Quelltext

1
2
3
4
bool Compare(const std::string& string1) const
{
    return string1 == "irgendwas";
}

Was meint ihr: Was ist der schnellste Weg, um Zeichenketten zu vergleichen? Sollte man std::string nutzen oder doch char[], um bessere Performance zu bekommen?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

13.04.2014, 13:54

Wenn die Performance von Stringvergleichen einen merklichen Einfluss auf deine Gesamtperformance hat, dann machst du was ganz grundlegend falsch... ;)

Abgesehen davon, würde ich mal schwer hoffen, dass std::string intern sowieso einfach std::strcmp verwendet und es also keinen Unterschied machen sollte...

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

3

13.04.2014, 14:50

Wenn es darum geht, "std::string"s zu vergleichen, wird das kaum einen Unterschied machen. "strcmp" wäre praktisch möglicherweise leicht langsamer, weil die Länge des Strings nicht bekannt ist was potentiell weniger Optimierungen ermöglich. Die STL des MSVC verwendet intern scheinbar "memcmp" zum Vergleich. Dafür bestimmt er erst die Stringlänge. Wenn der Compiler die Stringlänge nicht statisch bestimmt, könnte es zur Laufzeit einen kleinen Performanceverlust beim Vergleichen langer Strings mit "std::string" und "char*" geben. Ein explizite Angabe von "memcmp" mit statischer Länge könnte damit schneller sein.(Müsste man untersuchen). In komplexeren Situationen in denen der Compiler die Länge mit hoher Wahrscheinlichkeit nicht statisch auflöst, wäre das Vergleichen von "std::string"s mit langen "char*" somit potentiell uneffizient.

Wenn sich "std::string" selbst irgendwie vermeiden lässt, wäre das aber der viel viel größere Sprung. Intern besteht "std::string" nämlich aus einigen Overhead vorallendingend bestehend aus dynamischen Allokationen und der Small String "Optimization". Wenn man sehr viel mit Strings hantiert wird das spürbar sein. Der Längenvergleich selbst wohl eher weniger.

Wenn du den Vergleich selbst wirklich schneller machen wollen würdest, wäre eher soetwas wie das interessent: http://www.agner.org/optimize/#asmlib
Wenn man den Vergleichen im Manual Glauben schenken darf, ist seine Implementierung schneller. Möglicherweise haben sich inzwischen aber auch die Libs der Compiler weiterentwickelt.

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Spiele Programmierer« (13.04.2014, 15:02)


4

14.04.2014, 09:47

Wenn man in Betracht zieht, dass das Lexen gut die Hälfte der Kompilierzeit einer C++-Datei ausmacht, ist die Frage in der Compiler-Entwicklung schon ziemlich angebracht.

Der optimale Fall hängt aber, wie immer, vom Anwendungsfall ab: Wenn man Schlüsselwörter ohne Groß- oder Kleinschreibung zuordnen möchte, lohnt es sich, ein cmpAnyCaseToUpperCase(str, "KEYWORD") zu schreiben. Dann muss man auch testweise Optimierungen unterdrücken (wenn ein Compiler Vergleiche mit statischen Strings abrollt oder zu State Machines umbaut, könnte das stark kontraproduktiv sein).

Wenn man lange Wörter vergleichen muss und garantiertes Padding hat, lohnt sich – wie immer – Vektorisierung; siehe Implementing strcmp, strlen, and strstr using SSE 4.2 instructions (ich weiß nicht, ob Agner das auch so gemacht hat).

Und handelt es sich bei den Strings nicht um ASCII/ANSI sondern um Unicode, zieht man am besten in ein Kloster nach Tibet bis man sich von jedem Konzept einer sogenannten Performance losgesagt hat.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

5

14.04.2014, 12:55

Ich habe gerade mal schnell in den Source geschaut: Er nutzt SSE4.2 wenn es sinnvoll ist. Beim prinzipiell eh vorteilhaften "memcmp" allerdings nicht, weil es da auch keinen Vorteil bringen sollte. Dafür nutzt er auch AVX2.

Werbeanzeige