Wow; entschuldigt, dass ich erst jetzt Zeit zum Antworten habe.
joggel hat geschrieben:Also... wenn du hier etwas fragst, dann verstehe ich meist kaum die Frage^^.
Aber, mir fällt hier nur eins ein:
ASCIIs einfach anhand des Zahlenwertes vergleichen?
Jeder ASCII-Wert wird ja durch einen Zahlenwert dargestellt...
Ein cast pro Zeichen und dann vergleichen.
Oder gibt es da noch mehr zu beachten?
okay... anscheinend doch...
Gruß
Darauf antworte ich gern – kann ja nicht schaden, das Problem noch einmal von vorn bis hinten zu überdenken.
Also: Richtig; im ASCII wird jedes Zeichen durch einen Zahlenwert repräsentiert. Dabei haben aber auch Groß- und Kleinbuchstaben unterschiedliche Werte – sonst könnte ein Programm ja nicht zwischen Groß und Klein unterscheiden.
Der Vergleich läuft also für alle nicht-Buchstaben-Zeichen (Zahlen, Punkte, Sonderzeichen) mit direktem Vergleich der Zahlenwerte ab. Buchstaben sind ein Sonderfall: Hier muss jeder Zahlenwert zu
zwei Zahlenwerten gleichwertig sein (
b z.B. für
b und
B).
Die Frage ist nun, wie dieser Sonderfall möglichst performant verarbeitet werden soll: Sprünge verursachen Datenabhängigkeiten und lassen die Pipeline des Prozessors hungern; Nachschlagetabellen behindern den Cache.
eXile hat geschrieben:Krishty hat geschrieben:Ideen?
Ich plädiere auf String in Großbuchstaben umwandeln und strcmp anwenden, da letzteres dank SSE 4 mit dem
_mm_cmpistri-Intrinsic den String ziemlich flott wegfuttern kann.
Bringt nichts, weil die meisten Strings drei bis zehn Buchstaben lang sind. Ich möchte auch gerne erst bei SSE 2 bleiben, weil ich XP- und x86-kompatibel bleiben muss …
… es geht um das Erkennen von Schlüsselwörtern in Quelltext. Die Parallelisierung über zwei oder vier Buchstaben hinaus ist höchstwahrscheinlich völlig nutzlos.
kimmi hat geschrieben:@Krishty: kannst du deine Ergebnisse bei Zeiten hier mal präsentieren?
Ich habe noch keine; alles erst rein theoretisch

BeRsErKeR hat geschrieben:Man könnte einen kleinen Trick mit einer Art Lookup-Tabelle nutzen. Und zwar ist diese 2^7 (also 128) Bytes groß. Zu jedem ASCII-Zeichen wird ein Verundungs-Byte gespeichert. Für die meisten ist dies 255 (0xFF), für alle Kleinbuchstaben ist es 223 (0xDF).
Bei einem Stringvergleich bildet man den Absolutwert der Differenz beider ASCII-Werte und verundet diesen mit den beiden zugehörigen Werten aus der Lookup-Tabelle. Ist das Ergebnis 0 sind die Buchstaben gleich, sonst ungleich. Dadurch werden Klein- und Großbuchstaben als identisch erkannt. Man benötigt aber pro Buchstabe eine Subtraktion, eine Absolutwertbildung und 2 Lookups und Verundungen.
Auch eine interessante Methode. Die Absolutwertbildung lässt sich arithmetisch statt logisch durchführen; das würde aber trotzdem bei jeder Menge Datenabhängigkeiten bleiben.
BeRsErKeR hat geschrieben:Hmm eine einfache Lookup-Tabelle, die auf Großbuchstaben Kleinbuchstaben mappt wäre natürlich noch besser. Ich frage mich nur ob es schneller ist den Lookup beim Vergleich zweier Zeichen durchzuführen, oder vorher den gesamten String in Kleinbuchstaben umzuwandeln.
Das kommt darauf an, wie gleich die Strings im Schnitt sind. Wenn die meisten Strings sich direkt im ersten Buchstaben unterscheiden, ist ein Vergleich direkt nach dem Nachschlagen sicher schneller, weil sofort abgebrochen werden kann. Bei der anderen Methode müsste der komplette String konvertiert werden; selbst, wenn sich die Zeichen eindeutig unterscheiden. Dazu kommt die Frage, wo man die konvertierten Strings zwischenspeichern möchte.
Florian Keßeler hat geschrieben:Bei entsprechender Verwendung geeigneter Datentypen würde ich aber vermuten, dass ein ausreichend guter Compiler das sowieso so macht...
Nein, denn der Compiler weiß weder, wie lang die einzelnen Strings sind, noch, ob der überzählige Speicher bei Längen, die nicht ein Vielfaches der Wortgröße sind, gleich ist.
dot hat geschrieben:Also ich würd in erster Linie mal was in Richtung Bitgeschupse suchen. Immerhin unterscheiden sich die ASCII Codes der Groß- und Kleinbuchstaben nur in einem einzelnen Bit (eben genau um diesen Vergleich einfacher zu gestalten).
Das sechste Bit auf 0 setzen, vergleichen und bei Gleichheit schauen ob das Byte aus dem Bereich [65, 90] ist, ist alles was du tun musst. Das sollte sich doch irgendwie einfach realisieren lassen...
Prüfen, ob ein Byte in einem bestimmten Bereich ist, geht laut Bit Twiddling Hacks mit 7 arithmetischen Operationen; dazu noch ein kleines Bisschen Logik, um das
& nur in diesem Fall anzuwenden. Das muss für beide Buchstaben geschehen, bevor der endgültige Vergleich durchgeführt werden kann. Keine Ahnung, wie einfach man das kriegt … danke für den Quelltext; aber, wie gesagt, sind meine Strings dafür viel zu kurz.
Ich schätze, dass letztendlich absolut garnichts daran vorbeiführt, zu benchen … die Zahl der Datenabhängigkeiten und Sprünge bleibt bei allen Lösungen fast konstant; die Optimierungsfrage läuft – so, wie ich das einschätze – nur darauf hinaus, welches von beiden schneller ist.