在 C# 中使用按位运算符而不是普通的 int 总和会带来显着的性能提升吗?
几周前我开始使用 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 的隐式转换三元运算符非常相似。我现在的问题是:使用第一个版本比第二个版本有任何性能改进吗?
谢谢
托马索
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您绝对应该为枚举使用 Flags 属性。这样它看起来就像这样:
有了这个,你可以做这样的事情:
并通过以下方式检查每个状态:
You should definitely use the Flags attribute for your enum. That way it would look something like that:
With this you can do such things like:
and check for each state by:
内联
if
运算符(?
,:
)将生成与标准if
列表几乎相同的 IL。第二个例子。您在这里看到的唯一区别是处理器将执行的特定操作,我敢打赌ADD
比SHL
更快。由于无论如何您都会添加结果,因此我会选择第二个示例(而且它更易于阅读)。
编辑
我刚刚检查了两个示例的 IL,它与我上面所说的相悖。
第一个示例生成的 IL 少得多(少了 34 行),因此您必须运行性能测试才能真正确定它是否也更快。
The inline
if
operator (?
,:
) will generate nearly the same IL as the standardif
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 thatADD
is quicker thanSHL
.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.
明显更快?不。稍微快一点?一点点。
Significantly faster? no. Slightly faster? A little bit.