Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any significant performance improvement by using bitwise operators instead of plain int sums in C#?

I started working with C# a few weeks ago and I'm now in a situation where I need to build up a "bit set" flag to handle different cases in an algorithm. I have thus two options:

    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);

Or:

    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;   }

I could have used something as ((eye.X > maxCorner.X) << 1) but C# does not allow implicit casting from bool to int and the ternary operator was similar enough. My question now is: is there any performance improvement in using the first version over the second?

Thank you
Tommaso

like image 545
tunnuz Avatar asked May 17 '10 08:05

tunnuz


2 Answers

You should definitely use the Flags attribute for your enum. That way it would look something like that:

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

With this you can do such things like:

var position = RelativePositionings.Left | RelativePositionings.Front;

and check for each state by:

if(position.HasFlag(RelativePositioning.Left))
{
    //To do: if left bit is set?
}
like image 104
Oliver Avatar answered Oct 25 '22 06:10

Oliver


The inline if operator (?, :) will generate nearly the same IL as the standard if list in the second example. The only difference you will see here are the particular operations the processor will be doing, and I can bet that ADD is quicker than SHL.
Since you're going to be adding the results anyway, I would opt for the second example (plus it makes it far easier to read).

EDIT
I just checked the IL of both examples, and it goes against what I have said above.
The first example generates far less IL (34 lines less) so you'll have to run a performance test to really determine if it is faster too.

like image 43
Codesleuth Avatar answered Oct 25 '22 06:10

Codesleuth