2016-06-10 8 views
3

Unter diesem einfachen Vergleich loopValue == "Firstname", ist die folgende Aussage wahr?String Vergleich in der Kernsprache

Wenn der interne Operand die ersten char Inspektion nicht den im Vergleich Zeichenfolge übereinstimmt, wird es früh abbrechen

So die raueren Schrift loopValue und "Firstname" beide []byte sind. Und es würde Spaziergang die Anordnung wie eine Art, um Callback-Schleife für die Wahrheit:

someInspectionFunc(loopValue, "Firstname", func(charA, charB) { 
    return charA == charB 
}) 

... so dass es auf dem Gehen zu halten, bis es false und Kontrollen Bumps wenn die Anzahl der iterations gleich war sowohl ihre Längen . Prüft es auch zuerst die Länge?

if len(loopValue) != len("Firstname") { 
    return false 
} 

Ich kann nicht wirklich eine Erklärung in den go Quellcode auf GitHub finden, da es über mir ein bisschen ist.

Der Grund, warum ich das frage ist, weil ich große Datenverarbeitung bin und bin Benchmarking und CPU, Speicher und Allokation pprof zu tun, um etwas mehr Saft aus dem Prozess zu quetschen. Von diesem Prozess hat es mich irgendwie zum Nachdenken gebracht, wie Go (aber auch nur C im Allgemeinen) das unter der Haube machen würde. Ist dies vollständig auf einer Assembly-Ebene oder findet der Vergleich bereits im nativen Go-Code statt (wie oben in den Snippets skizziert)?

Bitte lassen Sie mich wissen, wenn ich zu vage bin oder etwas verpasst habe. Danke

aktualisieren

Wenn ich ein firstCharater Spiel in großen Ketten von json tat, bevor ich über 3.7% Benchmarking Gewinn auf 100k schweren Einträge wirklich zu vergleichen:

<some irrelevant inspection code>.. v[0] == firstChar && v == lookFor { 
    // Match found when it reaches here 
} 

den obigen Code (besonders auf langen Saiten) ist schneller als nur für v == lookFor gehen.

+0

ja, wird dies in der Montage durchgeführt, durch die 'Laufzeit · eqstring 'Funktion – JimB

+0

Vielen Dank für Ihre Antwort JimB. Wissen Sie, wie dieser Prozess bei der Inspektion abläuft? Wird die Länge der Variablen immer vollständig iteriert und/oder wird sie vorzeitig abgebrochen, wenn die gleiche Indextiefe nicht mehr übereinstimmt? –

+0

Nein, es vergleicht immer zuerst die Länge. Es gibt keinen Grund zu iterieren, wenn sie nicht gleich lang sind. – JimB

Antwort

6

Die Funktion wird in der Baugruppe behandelt. Die amd64 Version ist:

TEXT runtime·eqstring(SB),NOSPLIT,$0-33 
    MOVQ s1str+0(FP), SI 
    MOVQ s2str+16(FP), DI 
    CMPQ SI, DI 
    JEQ eq 
    MOVQ s1len+8(FP), BX 
    LEAQ v+32(FP), AX 
    JMP runtime·memeqbody(SB) 
eq: 
    MOVB $1, v+32(FP) 
    RET 

Und es ist die Aufgabe des Compilers, um sicherzustellen, dass die Saiten gleich lang sind vorher genannt wird. (Die runtime·memeqbody Funktion tatsächlich ist, wo die optimierte Speicher Vergleiche passieren, aber es ist wahrscheinlich nicht notwendig, den vollständigen Text hier posten)

Der entsprechende Code Go wäre:

func eqstring_generic(s1, s2 string) bool { 
    if len(s1) != len(s2) { 
     return false 
    } 
    for i := 0; i < len(s1); i++ { 
     if s1[i] != s2[i] { 
      return false 
     } 
    } 
    return true 
} 
+0

Ich habe NASM auf einem alten Mac vor Jahren gemacht. Ich sollte wirklich wieder darauf eingehen, um auch in dieser Größenordnung debuggen zu können :). Ich werde dies abstimmen, wenn die Cooldown-Zeit vorbei ist. Vielen Dank für die Zusammenarbeit wie immer JimB! –