2010-05-17 5 views
7

Ich begann vor ein paar Wochen mit C# zu arbeiten und bin jetzt in einer Situation, in der ich ein "Bit-Set" -Flag erstellen muss, um verschiedene Fälle in einem Algorithmus zu behandeln. Ich habe also zwei Möglichkeiten:Jede signifikante Leistungsverbesserung durch die Verwendung von bitweisen Operatoren anstelle von einfachen int-Summen in C#?

enum RelativePositioning 
    { 
     LEFT = 0, 
     RIGHT = 1, 
     BOTTOM = 2, 
     TOP = 3, 
     FRONT = 4, 
     BACK = 5 
    } 

    pos = ((eye.X < minCorner.X ? 1 : 0) << (int) RelativePositioning.LEFT) 
     + ((eye.X > maxCorner.X ? 1 : 0) << (int) RelativePositioning.RIGHT) 
     + ((eye.Y < minCorner.Y ? 1 : 0) << (int) RelativePositioning.BOTTOM) 
     + ((eye.Y > maxCorner.Y ? 1 : 0) << (int) RelativePositioning.TOP) 
     + ((eye.Z < minCorner.Z ? 1 : 0) << (int) RelativePositioning.FRONT) 
     + ((eye.Z > maxCorner.Z ? 1 : 0) << (int) RelativePositioning.BACK); 

Oder:

enum RelativePositioning 
    { 
     LEFT = 1, 
     RIGHT = 2, 
     BOTTOM = 4, 
     TOP = 8, 
     FRONT = 16, 
     BACK = 32 
    } 

    if (eye.X < minCorner.X) { pos += (int) RelativePositioning.LEFT; } 
    if (eye.X > maxCorner.X) { pos += (int) RelativePositioning.RIGHT; } 
    if (eye.Y < minCorner.Y) { pos += (int) RelativePositioning.BOTTOM; } 
    if (eye.Y > maxCorner.Y) { pos += (int) RelativePositioning.TOP; } 
    if (eye.Z > maxCorner.Z) { pos += (int) RelativePositioning.FRONT; } 
    if (eye.Z < minCorner.Z) { pos += (int) RelativePositioning.BACK; } 

ich etwas als ((eye.X > maxCorner.X) << 1) verwendet haben könnte, aber C# erlaubt es nicht, implizites Casting von Bool auf int und der ternäre Operator war ähnlich genug. Meine Frage ist nun: Gibt es eine Leistungsverbesserung bei der Verwendung der ersten Version über die zweite?

Danke
Tommaso

+8

Benchmark vor mikro- Durchführung Optimierungen –

+0

Stimmen Sie mit Mitch Wheat überein. Ziehen Sie auch die Lesbarkeit der Leistung vor, es sei denn, Sie können mit einem Profiler einen Engpass nachweisen. – OregonGhost

+4

"Wir sollten kleine Wirkungsgrade vergessen, sagen etwa 97% der Zeit: vorzeitige Optimierung ist die Wurzel allen Übels" Donald Knuth – Cagdas

Antwort

5

Der Inline if Operator (?, :) fast die gleichen IL als Standard if Liste im zweiten Beispiel generieren. Der einzige Unterschied, den Sie hier sehen werden, sind die speziellen Operationen, die der Prozessor ausführt, und ich kann wetten, dass ADD schneller ist als SHL.
Da Sie die Ergebnisse sowieso hinzufügen werden, würde ich für das zweite Beispiel entscheiden (plus es macht es viel einfacher zu lesen).

EDIT
Ich habe gerade überprüft die IL beider Beispiele, und es geht gegen das, was ich oben gesagt habe.
Das erste Beispiel erzeugt weit weniger IL (34 Zeilen weniger), also müssen Sie einen Leistungstest durchführen, um wirklich festzustellen, ob es auch schneller ist.

+0

+1 für die Bearbeitung. –

0

Deutlich schneller? Nein. Etwas schneller? Ein bisschen.

8

Sie sollten unbedingt die Flags attribute für Ihre enum verwenden. Auf diese Weise es so etwas wie das aussehen würde:

[Flags] 
public enum RelativePositionings 
{ 
    None = 0, 
    Left = 1, 
    Right = 2, 
    Bottom = 4, 
    Top = 8, 
    Front = 16, 
    Back = 32 
} 

Mit diesem können Sie solche Dinge wie:

var position = RelativePositionings.Left | RelativePositionings.Front; 

und prüfen Sie für jeden Zustand von:

if(position.HasFlag(RelativePositioning.Left)) 
{ 
    //To do: if left bit is set? 
} 
Verwandte Themen