通过在C#中使用按位运算符而不是普通的int和,可以显着提高性能?

时间:2010-05-17 08:17:58

标签: c# performance int bit-manipulation

几周前我开始使用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);

或者:

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

我本可以使用((eye.X > maxCorner.X) << 1)的东西,但是C#不允许从bool到int的隐式转换,并且三元运算符足够相似。我现在的问题是:使用第一个版本比第二个版本有任何性能提升吗?

谢谢你 托马索

3 个答案:

答案 0 :(得分:8)

你绝对应该使用Flags attribute作为你的枚举。这样看起来就像那样:

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

有了这个,你可以这样做:

var position = RelativePositionings.Left | RelativePositionings.Front;

并通过以下方式检查每个州:

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

答案 1 :(得分:5)

内联if运算符(?:)将生成与第二个示例中的标准if列表几乎相同的IL。您将在此处看到的唯一区别是处理器将要执行的特定操作,我敢打赌ADDSHL更快。 既然你还是要添加结果,我会选择第二个例子(加上它会让你更容易阅读)。

<强> 修改
我刚检查了两个例子中的IL,这与我上面所说的相反 第一个例子生成的IL少得多(少了34行),所以你必须运行一个性能测试来真正确定它是否也更快。

答案 2 :(得分:0)

明显更快?没有。稍微快点?一点点。