2

我正在尝试获得使用 C#.NET 处理位的基本技能。我昨天发布了一个示例,其中包含一个需要位操作的简单问题,这使我发现有两种主要方法 - 使用bitwise operators或使用 .NET 抽象,例如BitArray(如果有更多内置工具可以使用,请告诉我.NET以外BitArray的其他位以及如何为他们找到更多信息(如果有的话?)。

我知道bitwise operators工作更快,但使用BitArray对我来说更容易,但我真正要避免的一件事是学习不良做法。尽管我个人偏好 .NET 抽象,但我想知道在实际程序中学习和使用哪个更好。考虑到它,我很想认为 .NET 抽象并没有那么差,毕竟必须有理由在那里,也许作为初学者学习抽象更自然,然后通过低级操作提高我的技能,但这只是随机的想法。

4

3 回答 3

4

这真的取决于你用它做什么。当速度更受关注时,我会说使用按位运算,因为它们的开销要少得多。否则,BitArray 应该没问题。相关的主要开销是函数调用和您可以做的“技巧”的一些限制。

例如,如果您想在位 0、3 或 4 中设置一个值时执行某项操作:

if((value & 0b11001)>0) //not sure this is valid syntax, but you get the idea
{
   //do stuff
}

因为整数是原生 CLR 类型,所以几乎直接转换为 3 个原生操作码mov、、、andcmp

至于BitArray,我看到的最有效的方法是:

if(value[0] || value[3] || value[4])
{
  //...
}

其中(假设不是 JIT),这等于最多 3 个简单复杂的函数调用。从 BitArray 的支持整数(我假设)获取位值的最简单方法如下所示:

bool GetBit(int which)
{
  return value & (1 << which)>0;
}

这基本上意味着它相当于慢了大约 2 倍对于这个超级简单的情况,这意味着慢了大约 6 倍,因为我们正在检查 3 位。

而且对于 BitArrays,副本可能更昂贵,因为它们不是本机 CLR 类型。我怀疑这种开销在很大程度上已经被 JIT 消除了,但仍然需要考虑,尤其是在针对紧凑框架的情况下。

基本上,仅当您不需要对它们进行复杂的按位运算时才使用 BitArrays。

注意:您也可以使用混合方法在整数和 BitArrays 之间进行转换,但这也会产生相当多的开销。

于 2012-09-13T15:43:21.187 回答
3

我想知道在实际程序中我实际上更好地学习和使用哪个。

学习他们两个。它们并不难理解,您可以想象一个比另一个更好的场景。

虽然我同意上面的@Marc Gravell,但如果我有大量需要处理的位(并且速度不是太大问题),我只会考虑使用 BitArray,但如果你最终在这种情况下,你可能做错了什么。

于 2012-09-13T15:42:38.503 回答
3

编程时始终牢记这一点:

“没有什么问题是再增加一层间接解决不了的,除了间接层太多的问题”。——大卫·惠勒(段落)

通过使用 BitArray,您添加了一个间接层,该层抽象出如何管理位以及生成和操作每个位的值的细节。这通常是一件好事,值得鼓励;它创建更简洁、更优雅、更易于阅读的代码。

但是,当您需要做一些复杂的事情时会发生什么,而 BitArray 不允许您做(或很难做到)?那时,您的设计“过于抽象”;抽象级别阻止您做您想做的事情,因为它们“愚蠢”了太多。这是用更少的抽象进行重构的信号,在这种情况下,使用需要更多注意和理解的位运算符,但基本上会对一组位做任何可能的事情。

所以简而言之,使用 BitArray 来解决你的问题,直到使用 BitArray 成为它自己的问题。不要担心没有 BitArray 会做什么;这可能会担心是否以及何时需要这样做。只是不要忘记如何使用按位运算符,或者它们存在。

于 2012-09-13T15:43:17.630 回答