2016-05-22 26 views
-4

Die ursprüngliche Frage wurde schlecht erhalten und erhielt viele Downvotes. Also dachte ich mir, ich würde die Frage überarbeiten, um es leichter zu lesen und hoffentlich für jeden, der es sieht, hilfreicher zu sein. Die ursprüngliche Frage war, warum strlen() 20 Mal schneller war als manuell durch die Zeichenfolge zu durchlaufen und das Zeichen "\ 0" zu finden. Ich dachte, diese Frage sei begründet, da ich überall, wo ich Strlen() gelesen habe, die Länge der Zeichenkette im Grunde so lange durchläuft, bis sie ein Null-abschließendes Zeichen '\ 0' findet. Dies ist eine häufige Kritik an C-Strings aus mehreren Gründen. Viele Leute haben darauf hingewiesen, dass Funktionen, die Teil der C-Bibliothek sind, von intelligenten Programmierern erstellt werden, um die Leistung zu maximieren.Warum ist strlen() etwa 20-mal schneller als das manuelle Schleifen, um nach null-terminierten Zeichen zu suchen?

Dank iilen2, der mich mit einer SEHR cleveren Art verbunden hat, bitweise Operatoren zu verwenden, um 8 Bytes gleichzeitig zu überprüfen, habe ich etwas bekommen, das an einer Zeichenfolge größer als ungefähr 8 bis 15 Zeichen schneller als strlen läuft (), und viele Male schneller als strlen(), wenn die Saite wesentlich größer ist. Zum Beispiel, und seltsamerweise scheint strlen() linear abhängig von der Länge der zu beendenden Saite zu sein. Auf der anderen Seite, die benutzerdefinierte dauert fast die gleiche Menge an Zeit, unabhängig von der Länge der Saite (Ich habe bis zu ein paar hundert getestet). Wie auch immer, meine Ergebnisse sind ziemlich überraschend, ich habe sie mit ausgeschalteter Optimierung gemacht, und ich weiß nicht, wie gültig sie sind. Vielen Dank an ilen2 für die Verbindung und John Zwinck. Interessanterweise schlug John Zwinck SIMD als eine Möglichkeit vor, warum strlen() schneller sein könnte, aber ich weiß nichts darüber.

+1

Ihre Implementierung zum Zählen von Zeichen verwendet zwei Zusätze pro Schleife. Ich kann mir einen Weg vorstellen, bei dem nur 1 hinzugefügt wird. – ilent2

+5

Einer ist ein Bibliotheksaufruf zu einer optimierten Bibliothek, der andere ist ein Haufen nicht optimierter Assembly auf einem schlecht optimierten Algorithmus? Das ist so, als würde man fragen: "Warum kocht der Ofen Eier schneller, als sie in eine Tüte neben dem Kühlschrank zu legen?" – Yakk

+3

Ich würde auch erwarten, dass der Compiler mit optimierten Optimierungen feststellen könnte, dass das Berechnen der Stringlänge zur Kompilierzeit erfolgen kann, also ist dies nicht das beste Beispiel. Ein besseres Beispiel könnte sein, zuerst Strings unterschiedlicher Länge in den Speicher zu laden (aus einer Datei oder anderswo) und dann ihre Länge zu bestimmen. – ilent2

Antwort

5

strlen() ist eine sehr stark getroffene Funktion und Sie können wetten, dass mehrere sehr helle Leute Tage und Monate damit verbracht haben, sie zu optimieren. Sobald Sie Ihren Algorithmus richtig verstanden haben, können Sie als nächstes mehrere Bytes gleichzeitig prüfen. Die Antwort ist natürlich, dass Sie SIMD (SSE) oder andere Tricks verwenden können. Wenn Ihr Prozessor mit 128 Bits gleichzeitig arbeiten kann, sind das 16 Zeichen pro Takt anstelle von 1.

+0

Ich schrieb etwas basierend auf dem Link, den ient2 gab, es überprüft 8 Bytes auf einmal und so weit vom Testen ist es 4-mal schneller als strlen(), ich bin so glücklich, aber es gibt mehr Arbeit zu tun. Es wäre interessant, SIMD zu verwenden, ich hätte keine Ahnung, wie man es benutzt. – Zebrafish