Welche Methode eignet sich am besten (idomatischer) zum Testen nicht leerer Zeichenfolgen (in Go)?
if len(mystring) > 0 { }
Oder:
if mystring != "" { }
Oder etwas anderes?
Beide Stile werden in den Standardbibliotheken von Go verwendet.
if len(s) > 0 { ... }
finden Sie im strconv
Paket: http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
finden Sie im encoding/json
Paket: http://golang.org/src/pkg/encoding/json/encode.go
Beide sind idiomatisch und klar genug. Es geht eher um den persönlichen Geschmack und um Klarheit.
Russ Cox schreibt in einem Golang-Nuss-Thread :
Derjenige, der den Code klar macht.
Wenn ich mir Element x anschaue, schreibe ich normalerweise
len (s)> x, sogar für x == 0, aber wenn mir
"ist es diese spezielle Zeichenfolge" wichtig ist, schreibe ich eher s == "".Es ist anzunehmen, dass ein ausgereifter Compiler
len (s) == 0 und s == "" in denselben effizienten Code kompiliert.
...Machen Sie den Code klar.
Wie in der Antwort von Timmmm ausgeführt , generiert der Go-Compiler in beiden Fällen identischen Code.
if mystring != "" { }
ist der beste, bevorzugte und idiomatische Weg HEUTE. Der Grund, warum die Standardbibliothek etwas anderes enthält, ist, dass sie vor 2010 geschrieben wurde, als dielen(mystring) == 0
Optimierung sinnvoll war.len
, um leere / nicht leere Zeichenfolgen zu überprüfen. So ein Commit von Brad Fitzpatrick. Ich fürchte, es ist immer noch eine Frage des Geschmacks und der Klarheit;)len(v) > 0
in h2_bundle.go (Zeile 2702). Es wird nicht automatisch angezeigt, da es aus golang.org/x/net/http2 generiert wird, glaube ich.Dies scheint eine vorzeitige Mikrooptimierung zu sein. Dem Compiler steht es frei, für beide Fälle oder zumindest für diese beiden Fälle denselben Code zu erstellen
und
weil die Semantik eindeutig gleich ist.
quelle
Das Überprüfen der Länge ist eine gute Antwort, aber Sie können auch eine "leere" Zeichenfolge berücksichtigen, die ebenfalls nur aus Leerzeichen besteht. Nicht "technisch" leer, aber wenn Sie überprüfen möchten:
quelle
TrimSpace
wird eine neue Zeichenfolge aus der ursprünglichen Zeichenfolge zuweisen und kopieren, sodass dieser Ansatz zu Ineffizienzen bei der Skalierung führt.s
Typs[0:i]
eine neue Kopie zurückgibt. Strings sind in Go unveränderlich. Muss hier also eine Kopie erstellt werden?strings.TrimSpace( s )
keine neue Zeichenfolgenzuweisung und Zeichenkopie, wenn die Zeichenfolge nicht gekürzt werden muss. Wenn die Zeichenfolge jedoch gekürzt werden muss, wird die zusätzliche Kopie (ohne Leerzeichen) aufgerufen.gocritic
Linter schlägt vor,strings.TrimSpace(str) == ""
anstelle der Längenprüfung zu verwenden.Angenommen, leere Leerzeichen und alle führenden und nachfolgenden Leerzeichen sollten entfernt werden:
Weil :
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
quelle
< 1
+1Ab sofort generiert der Go-Compiler in beiden Fällen identischen Code, daher ist es Geschmackssache. GCCGo generiert zwar anderen Code, aber kaum jemand verwendet ihn, sodass ich mir darüber keine Sorgen machen würde.
https://godbolt.org/z/fib1x1
quelle
Es wäre sauberer und weniger fehleranfällig, eine Funktion wie die folgende zu verwenden:
quelle
Nur um mehr zum Kommentar hinzuzufügen
Hauptsächlich darüber, wie Leistungstests durchgeführt werden.
Ich habe mit folgendem Code getestet:
Und die Ergebnisse waren:
Effektiv erreichen Varianten normalerweise nicht die schnellste Zeit und es gibt nur einen minimalen Unterschied (ca. 0,01 ns / op) zwischen der Höchstgeschwindigkeit der Variante.
Und wenn ich das vollständige Protokoll betrachte, ist der Unterschied zwischen Versuchen größer als der Unterschied zwischen Benchmark-Funktionen.
Es scheint auch keinen messbaren Unterschied zwischen BenchmarkStringCheckEq und BenchmarkStringCheckNe oder BenchmarkStringCheckLen und BenchmarkStringCheckLenGt zu geben, selbst wenn letztere Varianten 6-mal statt 2-mal enthalten sollten.
Sie können versuchen, ein gewisses Vertrauen in die gleiche Leistung zu gewinnen, indem Sie Tests mit modifiziertem Test oder innerer Schleife hinzufügen. Das geht schneller:
Das geht nicht schneller:
Beide Varianten sind normalerweise schneller oder langsamer als der Unterschied zwischen den Haupttests.
Es wäre auch gut, Teststrings (ss) mit einem Stringgenerator mit relevanter Verteilung zu generieren. Und haben auch variable Längen.
Ich habe also kein Vertrauen in den Leistungsunterschied zwischen den Hauptmethoden zum Testen leerer Zeichenfolgen in go.
Und ich kann mit einiger Sicherheit sagen, dass es schneller ist, leere Zeichenfolgen überhaupt nicht zu testen, als leere Zeichenfolgen zu testen. Außerdem ist es schneller, leere Zeichenfolgen zu testen, als 1 Zeichenfolge (Präfixvariante) zu testen.
quelle
Gemäß den offiziellen Richtlinien und aus Sicht der Leistung erscheinen sie gleichwertig ( ANisus-Antwort ), das s! = "" Wäre aufgrund eines syntaktischen Vorteils besser. s! = "" schlägt beim Kompilieren fehl, wenn die Variable keine Zeichenfolge ist, während len (s) == 0 für mehrere andere Datentypen übergeben wird.
quelle
len()
genau verstanden hat ... trotz aller Optimierungen auf der Welt ist nur ein wenig mehr Arbeit erforderlich. In C haben wir jedoch die linke Seite in a umgewandeltconst
oder die statische Zeichenfolge auf die linke Seite des Operators gesetzt, um zu verhindern, dass s == "" zu s = "" wird, was in der C-Syntax akzeptabel ist. .. und wahrscheinlich auch Golang. (siehe das erweiterte if)Dies wäre leistungsfähiger als das Trimmen der gesamten Zeichenfolge, da Sie nur nach mindestens einem einzelnen Nicht-Leerzeichen suchen müssen
quelle
Ich denke, der beste Weg ist, mit leeren Zeichenfolgen zu vergleichen
BenchmarkStringCheck1 prüft mit einer leeren Zeichenfolge
BenchmarkStringCheck2 prüft mit len zero
Ich überprüfe mit der leeren und nicht leeren Zeichenkettenprüfung. Sie können sehen, dass das Überprüfen mit einer leeren Zeichenfolge schneller ist.
Code
quelle