如果您想知道一个字节中是否设置了特定位,一个简单的 AND 掩码就可以解决问题。我想知道是否有更快的方法来实现同样的目标。例如,位移 << 或 >> 返回位移后的数字,而不是刚刚“脱落”的位。
如果托管代码中没有替代方案,编写不安全的程序集会使其更快吗?如果是这样,请解释如何。
上下文:这是针对需要针对生产代码进行高度优化的复杂算法。我觉得有必要澄清这一点,以避免可怕的“做你自己的功课”评论和/或投票否决。
如果您想知道一个字节中是否设置了特定位,一个简单的 AND 掩码就可以解决问题。我想知道是否有更快的方法来实现同样的目标。例如,位移 << 或 >> 返回位移后的数字,而不是刚刚“脱落”的位。
如果托管代码中没有替代方案,编写不安全的程序集会使其更快吗?如果是这样,请解释如何。
上下文:这是针对需要针对生产代码进行高度优化的复杂算法。我觉得有必要澄清这一点,以避免可怕的“做你自己的功课”评论和/或投票否决。
要通过移位操作执行位测试,您必须将其移位(无符号)两次,以从任一侧剔除多余的位(您无需将其放回任何特定位置 - 只需测试为零) . 这很复杂并且不是最优的。
奇怪的是,an&
是执行位测试的标准方式,并且已经过大量优化;这是一条单 CPU 指令,速度非常快。
只需使用&
测试,例如if((x & MASK) != 0)
.
不,unsafe
代码在这里不会真正帮助您。unsafe
主要对指针感兴趣。指针很有趣,但没有它们你也可以做完全相同的位测试。这里指针的一个潜在用途是,如果有某种方法可以使用指针强制来一次测试比最初情况更多byte[]
的数据,例如,如果你有一个,但你想一次测试 8 个字节,通过强制byte[]
to a byte*
,然后byte*
to a long*
or ulong*
。这可能是一个有用的优化,比如 web-socket 掩码(它使用更宽的 xor 掩码对字节流进行操作)。但是,对于简单的位测试,这些都不是必需的。
如前所述:按位运算非常高效。在任何现代处理器上,几乎可以肯定任何此类操作都在单个时钟周期内执行。
如果您想查看为您的表达式生成的实际代码,请在 Visual Studio 调试器中启动它。设置一个断点,当你点击它时,点击菜单:Debug..Windows..Disassembly。
也许,如果您的表达式足够复杂,您可以在这类事情上击败编译器和优化器,但我对此表示怀疑。更重要的是,您遇到的任何性能问题都不太可能与位旋转有关。在遇到问题之前不要进行优化。正如詹姆斯迈克尔黑尔所说:
记住优化的两条定律。我不确定我第一次听到这些的地方,但它们是如此真实:
- 对于初学者:不要优化。
- 对于专家:尚未优化。
这是真的。如果您是初学者,请抵制不惜一切代价进行优化的冲动。如果您是专家,请推迟该决定。只要你为你的任务选择了正确的数据结构和算法,你的表现可能就绰绰有余了。有可能是网络、数据库或磁盘命中会降低您的速度,而不是您的代码。正如他们所说,98% 的代码瓶颈存在于 2% 的代码中,因此过早的优化可能会增加不会产生任何可衡量影响的维护和安全债务。
取而代之的是,为了可维护性和安全性而编写代码,然后,只有这样,当您发现真正的瓶颈时,您才应该返回并进一步优化。
更多在这里:
请参阅Bit-Twiddling Hacks了解如何完成与位操作相关的任何事情。面向 C 语言,但相同的技术在 C# 中只需稍加修改即可工作(例如,任何涉及指针的事情都可能需要重新考虑)。