MonoDevelop schlägt vor, if-Anweisungen in bitweise Operationen umzuwandeln

8

MonoDevelop schlägt vor, das zu drehen:

%Vor%

hinein:

%Vor%

Es tut es auch, wenn ich stattdessen anotherBoolVar auf false setze:

%Vor%

wird zu:

%Vor%

Kann jemand erklären, wie diese Aussagen gleich sind?

    
foxneSs 26.03.2015, 13:33
quelle

6 Antworten

12

Nun, funktional sie sind gleichwertig.

Im ersten Fall möchten Sie anotherBoolVar auf true setzen, wenn someBoolVar auf true steht, unabhängig davon, welchen Wert anotherBoolVar momentan hat, der ersetzende Ausdruck tut das.

Es ist kurz:

%Vor%

Die zweite Ersetzung funktioniert genauso wie der Code, den sie ersetzt, und ist dafür kurz:

%Vor%

Die Lösung ist in diesem Fall durch die "bitweise" Natur boolescher Variablen verborgen. Zu und mit einem invertierten Wert ( ~ invertiert den someBoolVar ) sagt effektiv "behalte alle Bits, die in !someBoolVar gesetzt sind und lösche den Rest", was bedeutet, dass wenn someBoolVar ist wahr, es wird zu false invertiert, und Sie werden anotherBoolVar effektiv löschen.

Nun, sollten Sie das tun ?

Meiner Meinung nach, nein. Der Code ist besser lesbar. Bleiben Sie und suchen Sie möglicherweise nach einer Möglichkeit, MonoDevelop zu bitten, diese Dinge in Zukunft nicht mehr zu empfehlen.

    
Lasse Vågsæther Karlsen 26.03.2015, 13:37
quelle
3

IDE-Code-Empfehlungen sind oft ein Double Edge-Schwert. Ja, die Aussagen sind tERSE, ABER sie sind möglicherweise auch verwirrend (daher Ihr Nachdenken).

%Vor%

ist dasselbe wie

%Vor%

weil |= kurz-umschreibt, wenn someBoolVar falsch ist. Wenn someBoolVar true ist, wird es nicht kurzgeschlossen und weist daher den someBoolVar-Wert (true) einer anderenBoolVar zu.

Obwohl die etwas knappere Aussage leicht optimiert werden kann, empfehle ich Ihnen, bei Ihrer if-Anweisung zu bleiben, weil sie ausdrucksstarker und lesbarer ist.

Für diese Art von if-Anweisungen versuche ich, sie auf einer Zeile zu halten:

if (someBoolVar) anotherBoolVar = someBoolVar;

    
kingdango 26.03.2015 13:41
quelle
2

Für z.B.

%Vor%

Wenn someBoolVar also true ist, kommt es auf

%Vor%

wird immer als wahr ausgewertet.

    
Nikhil Agrawal 26.03.2015 13:38
quelle
2

Für die erste Änderung bedeutet die if Konstruktion:

%Vor%

Die |= Konstruktion bedeutet:

%Vor%

Ähnliches gilt für die zweite Änderung, obwohl, wie @Lasse V. Karlsen erwähnt hat, die &= -Konstruktion eine Tilde zu fehlen scheint.

    
Ross Presser 26.03.2015 13:40
quelle
1

Vielleicht hilft der Wikipedia-Artikel zur Booleschen Algebra.

Der Vorschlag ist eine Mikro-Optimierung, die Makro in Eile verwandeln kann. Der Just-in-Time-Compiler erzeugt eine bedingte Verzweigung für die if () -Anweisung, zumindest die von Microsoft erstellten sind nicht schlau genug, um den Code selbst zu optimieren. Sie müssen einen Blick darauf werfen, ob der Monojitter einen besseren Job machen kann, wenn Sie sich den generierten Maschinencode ansehen. Die typische Codegenerierung sieht folgendermaßen aus:

%Vor%

Bedingte Verzweigungen wie der JE-Befehl in dem obigen Maschinencode sind für einen modernen Prozessor lästig, er hängt stark von der Pipeline ab, um Code schnell ausführen zu lassen. Befehlsdecodierung und Micro-Ops-Generierung wird im Voraus durchgeführt. Auch eine große Sache für den Prefetcher, es versucht zu erraten, welche Speicherplätze in den Caches verfügbar sein müssen, damit die Ausführungsmaschine nicht zum Stillstand kommt, wenn der Speicherinhalt benötigt wird. Der Speicher ist sehr, sehr langsam im Vergleich zur rohen Ausführungsgeschwindigkeit der Ausführungs-Engine des Prozessors.

Ein Prozessor hat einen Verzweigungsprädiktor , er verfolgt, ob die Verzweigung ausgeführt wurde, als der Code zuvor ausgeführt wurde. Und nimmt an, dass sich der Zweig wieder genauso verhält. Wenn es falsch rät, muss die Pipeline geleert werden. Eine Menge Arbeit wird weggeworfen und der Prozessor wird stehen bleiben, während er wieder hochfährt. Zusätzliche Long-Ställe können auftreten, wenn der Prefetcher falsch geraten hat, hohe Chancen, dass es getan hat. Es gibt einen guten SO-Beitrag , der die Konsequenzen einer falschen Vorhersage erklärt.

Mit der Booleschen Algebra wird die Verzweigung vermieden, es wird eine OR- oder AND-Anweisung erzeugt, sie nehmen einen einzigen Zyklus und können die Pipeline niemals leeren. Sicherlich eine Mikro-Optimierung, es wird nur Makro, wenn dieser Code innerhalb der ~ 10% Ihres Codes befindet, bestimmt die Geschwindigkeit Ihres Programms. Die IDE wird nicht intelligent genug sein, um Ihnen zu sagen, ob das der Fall ist, nur ein Profiler kann Ihnen das zeigen.

Fwiw, es gibt mehr Mikro-Optimierungen wie diese, Programmierer neigen dazu, die & amp; & amp; und || Betreiber unangemessen. Das Kurzschließverhalten dieser Operatoren erfordert immer eine Verzweigung im Maschinencode. Dieses Verhalten wird nicht immer benötigt, normalerweise ist es nicht und die & amp; und | Operator kann viel schneller Code generieren. Wenn der linke Operand schlecht vorhergesagt wird, kann Code 500% langsamer werden.

    
Hans Passant 26.03.2015 14:19
quelle
0
%Vor%

entspricht

%Vor%

was äquivalent zu

ist %Vor%

weil x | Wahr == Wahr und x | falsch == x

und ich nehme an, Sie wissen das

%Vor%

entspricht

%Vor%     
James Barrass 26.03.2015 13:38
quelle