2012-09-13 48 views
2

我试图获得使用C#.NET位的基本技能。我昨天发布了一个例子,它带有一个简单的问题,需要进行位操作,这导致我有两个主要方法 - 使用bitwise operators或使用.NET抽象,例如BitArray(请让我知道是否有更多的内置工具可用于在.NET中使用除BitArray以外的位以及如何找到更多信息?)。按位运算符与C#中位操作的.NET抽象

据我所知,bitwise operators工作更快,但使用BitArray对我来说更容易一些,但我真正试图避免的一件事是学习不好的做法。尽管我的个人偏好是针对.NET抽象的,但我想知道我真的能更好地学习和使用真正的程序。思考它我很想去想.NET抽象并没有那么糟糕,毕竟必须有理由在那里,也许是一个初学者,学习抽象更自然,后来通过低级操作提高我的技能,但这只是随意的想法。

+5

不知道我怎样才能将这个短语作为完整的答案,但是:在我能想到的几乎每种常见的情况下,操作者方法都是优选的。我唯一需要看BitArray的是当我需要一个**任意大的**标记集时,a:非常罕见,而b:通过简单的字节数组或int数组实现是微不足道的*无论如何* –

+1

@MarcGravell,好评...为什么仍然没有那个神奇的“转换评论回答”按钮... –

+0

谢谢大家。很多有用的信息。 – Leron

回答

4

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

举例来说,如果你想要做的东西,如果位0,3,或4,其中设置一个值:

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

这是因为整型是本地CLR类型,转换几乎直接到只有3原生操作码,movand,并cmp

这里作为一个BitArray,我看到的最effecient的方法是这样的:

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

在哪里(假设不是JIT),这等于多达3个光复杂度函数调用。摆脱后盾整数位值的最简单方式BitArray的(我认为)是这样的:

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

这基本上意味着它相当于是2倍左右慢只是一位对于这个超级简单的情况下,这意味着我们正在检查3位比较慢6倍。

而且对于BitArrays,副本可能更昂贵,因为它们不是本机CLR类型。我怀疑这种开销大部分会被抛出,但仍然需要考虑,特别是如果面向一个紧凑的框架。

基本上只使用BitArrays,如果你不需要对它们进行复杂的按位运算。

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

+0

'cmp'可以被删除,因为'and'设置标志无论如何,然后''''可以通过将'和'更改为'test'来删除,这是无损的,所以这只是一条指令(理论上,无论如何,JIT编译器是否足够聪明?) – harold

+0

那么,它依赖于@harold,这是一个完全的猜测,因为它完全取决于JIT编译器。通过IL的工作方式,它是一系列的push,并且比较,if-true等等,所以这主要是我的我确定有人真的专注于可以看到JIT编译器本身编译的结果 – Earlz

+0

好吧,我测试了它,并且JIT编译器变得足够聪明,只需生成'test'指令即可。至少我测试它的版本,这是版本4. – harold

3

我想知道我真的更好地学习和使用真正的程序。

两人学习。他们并不那么难以理解,你可以想象一个人会比另一个人更好的场景。

尽管我同意上面的@Marc Gravell,如果我需要处理大量的位(并且速度不是太大的问题),我只会考虑使用BitArray,但如果你最终在这种情况下,反正你可能做错了什么。在任何时候都在编程时

3

请记住这一点:

“是没有问题的,可以不通过增加间接的另一层,来解决,除了具有间接的层次过多的问题” 。 - 大卫惠勒(对位)

通过使用BitArray,添加了一个间接层,其抽象出的位是如何管理和每个比特的值被产生和操纵的细节。这通常是一件好事,需要鼓励;它会创建更清晰,更优雅,更易于阅读的代码。

但是,当你需要做一些复杂的事情时,会发生什么?BitArray不允许你这样做(或者做起来非常困难)?那时候,你的设计“过于抽象”。抽象层次妨碍你做你想做的事情,因为他们太“愚蠢”了。这是一个信号重构抽象较少,在这种情况下,使用按位运算符需要更多的关心和理解,但基本上做任何事情可能做一组位。

因此,总之,使用BitArray解决您的问题,直到使用BitArray成为它自己的问题。如果没有BitArray,不要担心你要做什么;如果和有时是必要的,可以担心。不要忘记如何使用按位运算符,或者它们存在。

+1

+1。特别是“不要忘记如何使用按位运算符,或者它们存在。” :)我会在“使用BitArray解决您的问题”中稍微远一些 - 不要使用位操作/ BitArray,除非您知道它正是您所需要的(即,您从某处获取位标志或者解决了“多少个1在这个值的二进制表示)在你的大部分代码中,你永远不会使用 - 常规的'bool isReady'属性和字段显着易于阅读 –