在C#中的位移中捕获掉落的字节

时间:2012-08-06 21:31:14

标签: c# .net bit-manipulation

如果你想知道一个字节中是否设置了一个特定的位,一个简单的AND掩码可以解决问题。我想知道是否有更快的方法来实现同样的目标。作为示例,比特移位<<或>>返回移位的数字,而不是刚刚掉下来的位数。

如果托管代码中没有替代方法,那么编写不安全的程序集会让它更快吗?如果是,请解释如何。

上下文:这适用于需要针对生产代码进行高度优化的复杂算法。我认为有必要澄清这一点,以避免可怕的做自己的功课'评论和/或投票结果。

2 个答案:

答案 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#中几乎没有任何修改(例如,任何涉及指针的东西都可能需要重新思考)。