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