逐位运算符与.NET抽象,用于C#中的位操作



我正在努力掌握使用C#处理位的基本技能。NET。我昨天发布了一个例子,其中有一个需要位操作的简单问题,这让我发现有两种主要方法——使用bitwise operators或使用。NET抽象,如BitArray(请告诉我在.NET中是否有更多用于处理BitArray以外的位的内置工具,以及如果有,如何为它们找到更多信息?)。

我知道bitwise operators工作得更快,但使用BitArray对我来说要容易得多,但我真正想避免的一件事是学习坏习惯。尽管我的个人偏好是。NET抽象我想知道在实际的程序中,哪一个更适合学习和使用。想想看,我很想这么想。NET抽象并没有那么糟糕,毕竟一定有理由存在,也许作为一个初学者,学习抽象并在以后通过低级别操作提高我的技能是更自然的,但这只是随机的想法。

这实际上取决于你用它做什么。我想说,当速度更重要时,使用逐位操作,因为它们的开销要小得多。否则,BitArray应该没问题。相关的主要开销是函数调用和对你可以做的"技巧"的一些限制

例如,如果你想做一些事情,如果在值中设置了位0、3或4:

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

因为整数是本机CLR类型,所以几乎直接转换为3个本机操作码,movandcmp

对于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类型。我怀疑这种开销在很大程度上是多余的,但仍然需要考虑,尤其是在针对紧凑框架的情况下。

基本上,只有在不需要对BitArrays执行复杂的逐位操作的情况下,才使用BitArrays。

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

我想知道在真正的程序中,哪一个更适合学习和使用。

同时学习它们。它们并不难理解,你可以想象其中一个会比另一个更好的场景。

虽然我同意上面的@Marc Gravell的观点,但只有当我有大量的比特需要处理时,我才会考虑使用BitArray(速度不是太大的问题),但如果你最终陷入这种情况,你可能会做错什么。

编程时始终牢记这一点:

"没有任何问题不能通过添加另一层间接层来解决,除了有太多间接层的问题"。-David Wheeler(段落)

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

然而,当你需要做一些复杂的事情,而BitArray不允许你做(或者让你做起来非常困难)时,会发生什么?在这一点上,你的设计"过于抽象";抽象级别阻止了你做你想做的事情,因为它们太"愚蠢"了。这是一个用更少抽象进行重构的信号,在这种情况下,使用逐位运算符,需要更多的关心和理解,但基本上会对一组位做任何可能的事情。

简而言之,使用BitArray来解决您的问题,直到使用BitArray成为自己的问题。不用担心没有BitArray你会做什么;这可能会让人担心,如果有必要的话。只是不要忘记如何使用位运算符,或者它们的存在。

最新更新