Ruby: Ziel-losen "Fall", im Vergleich zu "wenn"

8

(Ich habe diese Frage bereits im Ruby Forum gestellt, aber es ist habe keine Antwort gezeichnet, also bin ich jetzt Crossposting)

Nach meinem Verständnis sind die folgenden Teile des Codes gleichwertig Ruby 1.9 und höher:

%Vor%

Bisher hätte ich immer (2) aus Gewohnheit benutzt. Könnte jemand denken aus einem bestimmten Grund, warum entweder (1) oder (2) "besser" ist, oder ist es einfach eine Frage des Geschmacks?

Erläuterung: Einige Benutzer haben eingewandt, dass diese Frage nur "meinungsbezogen" wäre und daher für dieses Forum nicht geeignet wäre. Ich denke deshalb, dass ich mich nicht klar genug ausgedrückt habe: Ich will keine Diskussion über den persönlichen Programmierstil beginnen. Der Grund, warum ich dieses Thema angesprochen habe, ist folgendes:

Ich war überrascht, dass Ruby zwei sehr unterschiedliche Syntaxen (ziellosen Fall und if-elsif) für, wie es mir scheint, den genau gleichen Zweck angeboten, insbesondere da die if-elsif-Syntax die eine virtuell ist Jeder Programmierer ist vertraut. Ich würde nicht einmal "zielloses wenn" als "syntaktischen Zucker" betrachten, weil es mir nicht erlaubt, die Programmierungslogik konsequenter als "if-elsif" auszudrücken.

Ich frage mich also, in welcher Situation ich das Konstrukt "Targetless Case" verwenden möchte. Gibt es einen Leistungsvorteil? Ist es anders als wenn ich es auf subtile Art und Weise mache, was ich einfach nicht bemerke?

ZUSÄTZLICHE ERGEBNISSE bezüglich der Umsetzung eines zielfreien Falles:

Olivier Poulin hat darauf hingewiesen, dass eine zielfreie Case-Anweisung explizit den Operator === gegen den Wert "wahr" verwenden würde, was eine (kleine) Leistungseinbuße des "Falls" im Vergleich zu "wenn" verursachen würde. (Und noch ein Grund, warum ich nicht sehe, warum jemand es benutzen möchte).

Beim Überprüfen der Dokumentation der Case-Anweisung für Ruby 1.9 und Ruby 2.0 habe ich jedoch festgestellt, dass sie es anders beschreiben, aber beide deuten zumindest darauf hin, dass == in diesem Fall NICHT verwendet werden sollte. Im Fall von Ruby 1.9 :

  

Case-Anweisungen bestehen aus einer optionalen Bedingung, die in der Position eines Arguments für case steht, und null oder mehr when-Klauseln. Die erste when-Klausel, die mit der Bedingung übereinstimmt (oder mit boolescher Wahrheit ausgewertet wird, wenn die Bedingung null ist), "gewinnt"

Hier heißt es, dass, wenn die Bedingung (d. h. was nach "case" kommt) null ist (d. h. nicht existiert), die erste "when" -Klausel, die wahr ist, diejenige ist, die ausgeführt wird. Kein Bezug auf === hier.

In Ruby 2.0 ist der Wortlaut völlig anders:

>
  

Der case-Ausdruck kann auf zwei Arten verwendet werden. Die gängigste Methode besteht darin, ein Objekt mit mehreren Mustern zu vergleichen. Die Muster werden mit der Methode + === + [.....] abgeglichen. Die andere Möglichkeit, einen Case-Ausdruck zu verwenden, ist wie ein if-elsif-Ausdruck: [Beispiel für einen ziellosen Fall wird hier angegeben].

Es besagt also, dass === auf die "erste" Weise (Fall mit Ziel) verwendet wird, während der ziellose Fall "wie" ist, wenn-elsif. Keine Erwähnung von === hier.

    
user1934428 30.06.2015, 15:45
quelle

1 Antwort

6
  

Midwire hat ein paar Benchmarks durchgeführt und festgestellt, dass wenn elsif schneller ist   als Fall, weil Fall "implizit vergleicht die Verwendung der teureren   === Operator ".

Hier habe ich dieses Zitat erhalten. Es vergleicht if / elsif -Anweisungen mit case .

Es ist sehr gründlich und erkundet die Unterschiede in der Anweisungsfolge, wird Ihnen definitiv eine Vorstellung davon geben, was besser ist.

Die Hauptsache, die ich aus dem Post herausgezogen habe, ist, dass sowohl if / else if als auch case keine großen Unterschiede haben, beide können normalerweise synonym verwendet werden.

Je nachdem, wie viele Fälle Sie haben, können sich große Unterschiede ergeben.

%Vor%

Wie Sie sehen können, ist if / elsif , wenn die letzte Klausel übereinstimmt, viel langsamer als case, während if der ersten Klausel entspricht, ist es umgekehrt .

Dieser Unterschied ergibt sich aus der Tatsache, dass if / elsif branchunless verwendet, während case in ihren Befehlssequenzen branchif verwendet.

Hier ist ein Test, den ich selbst gemacht habe, mit einer ziellosen case vs if / elsif Anweisung (mit "=="). Das erste Mal ist case , während das zweite Mal if / elsif ist.

Erster Test, 5 when -Anweisungen, 5 if / elsif , die erste Klausel ist für beide wahr.

%Vor%

Zweiter Test, 5 when -Anweisungen, 5 if / elsif , die letzte (5.) -Klausel gilt für beide.

%Vor%

Wie Sie bereits gesehen haben, gilt, wenn die erste Klausel zutrifft, wenn / elsif eine bessere Leistung als case, während case einen massiven Leistungsvorteil hat, wenn die letzte Klausel wahr ist.

SCHLUSSFOLGERUNG

Mehr Tests haben gezeigt, dass es wahrscheinlich auf Wahrscheinlichkeit ankommt. Wenn Sie denken, dass die Antwort früher in Ihrer Liste von Klauseln kommen wird, verwenden Sie if / elsif , sonst scheint case schneller zu sein.

Die Hauptsache, die dies gezeigt hat, ist, dass sowohl case als auch if / elsif gleichermaßen effizient sind und dass die Verwendung von einer über die andere auf Wahrscheinlichkeit und Geschmack zurückzuführen ist.

    
Olivier Poulin 30.06.2015, 15:49
quelle

Tags und Links