几周前我开始使用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的隐式转换,并且三元运算符足够相似。我现在的问题是:使用第一个版本比第二个版本有任何性能提升吗?
谢谢你 托马索
答案 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。您将在此处看到的唯一区别是处理器将要执行的特定操作,我敢打赌ADD
比SHL
更快。
既然你还是要添加结果,我会选择第二个例子(加上它会让你更容易阅读)。
<强> 修改 强>
我刚检查了两个例子中的IL,这与我上面所说的相反
第一个例子生成的IL少得多(少了34行),所以你必须运行一个性能测试来真正确定它是否也更快。
答案 2 :(得分:0)
明显更快?没有。稍微快点?一点点。