问题描述
1)。 VAR bitValue =(的byteValue及(1 LT;<位编号))!= 0;
2) 。使用 System.Collections.BitArray
与获取(位编号)方式
- 什么是快?
- 在什么情况下对.NET项目的 BitArray 可能比使用按位转移的简单结合更有用?
BitArray
将是能够处理布尔值的任意数量的,而字节
将仅持有8, INT
只有32等。这将是两者之间最大的区别。
此外, BitArray
工具的IEnumerable
,其中一个整体式显然不会。因此,一切都取决于你的项目的要求;如果你需要一个的IEnumerable
或数组一样的界面,然后用 BitArray
。
我真的使用布尔[]
以上任何一种解决方案,只是因为它是更加明确的的什么的那种数据你保持跟踪。 ŧ
BitArray
或位域
将使用约1 / 8日的空间布尔[]
,因为它们打包8布尔值到一个单字节,而布尔
本身会占用整个8位字节。使用位域的空间优势或 BitArray
不会,虽然事,直到你被存储的地段的的bool
。 (数学留给了读者:-))
基准
结果:我的原始测试环境中,似乎 BitArray
是位的速度更快,但震级是作为自己与整型做同样的顺序。还测试了一个布尔[]
,这是勿庸置疑的最快的。访问单字节的内存将是比访问不同的字节各个位那么复杂。
与千万操作测试:
一个UInt32的位域了808毫秒。
一个BitArray(32)574了毫秒。
的List<布尔>(32)采取了436毫秒。
代码:
类节目
{
静态无效的主要(字串[] args)
{
随机R =新的随机();
r.Next(1000);
const int的N =千万;
Console.WriteLine(测试与{0}操作,N);
Console.WriteLine(A UInt32的位域了{0}毫秒。TestBitField(R,N));
Console.WriteLine(A BitArray(32)采取了{0}毫秒。TestBitArray(R,N));
Console.WriteLine(A名单<布尔>(32)采取了{0}毫秒。TestBoolArray(R,N));
Console.Read();
}
静态长TestBitField(随机R,INT N)
{
UInt32的位域= 0;
变种SW = Stopwatch.StartNew();
的for(int i = 0; I< N;我++){$ B
$ B SetBit(REF位域,r.Next(32),TRUE);
布尔B = GETBIT(位字段,r.Next(32));
SetBit(REF位域,r.Next(32),B);
}
sw.Stop();
返回sw.ElapsedMilliseconds;
}
静态布尔GETBIT(UInt32的X,INT BITNUM){
如果(BITNUM℃,|| BITNUM> 31)
抛出新ArgumentOutOfRangeException(无效比特数);
则返回(x及(1下;&下; BITNUM))!= 0;
}
静态无效SetBit(参考UInt32的X,INT BITNUM,布尔VAL)
{
如果(BITNUM℃,|| BITNUM> 31)
抛出新ArgumentOutOfRangeException(无效的位号);
如果(VAL)
X | =(UInt32的)(1 <,否则
X - 放大器; =〜(UInt32的)(1 <}
静态长TestBitArray(随机R,INT N)
{
BitArray B =新BitArray(32,FALSE) ; // 40字节
变种SW = Stopwatch.StartNew();
的for(int i = 0; I< N;我++){$ B
$ B b.Set(r.Next(32),TRUE);
布尔V = b.Get(r.Next(32));
b.Set(r.Next(32),ⅴ);
}
sw.Stop();
返回sw.ElapsedMilliseconds;
}
静态长TestBoolArray(随机R,INT N)
{
布尔[] BA =新布尔[32] ;
变种SW = Stopwatch.StartNew();
的for(int i = 0; I< N;我++){$ B
$ B BA [r.Next(32)] =真;
布尔V = BA [r.Next(32)];
BA [r.Next(32)] = v的
}
sw.Stop();
返回sw.ElapsedMilliseconds;
}
}
1). var bitValue = (byteValue & (1 << bitNumber)) != 0;
2). using System.Collections.BitArray
with a Get( bitNumber ) method
- What is faster?
- In what situations for the .NET projects BitArray could be more useful than a simple conjunction with the bitwise shift?
BitArray
is going to be able to handle an arbitrary number of boolean values, whereas a byte
will hold only 8, int
only 32, etc. This is going to be the biggest difference between the two.
Also, BitArray
implements IEnumerable
, where a integral type obviously does not. So it all depends on the requirements of your project; if you need an IEnumerable
or array-like interface, then go with the BitArray
.
I would actually use a bool[]
over either solution, simply because it is more explicit in what kind of data you're keeping track of. T
BitArray
or bitfield
will use approximately 1/8th the space of a bool[]
because they "pack" 8 boolean values into a single byte, whereas a bool
by itself will take up the whole 8-bit byte. The space advantage of using a bitfield or BitArray
isn't going to matter though until you being storing lots of bools
. (The math is left up to the reader :-))
Benchmark
Results: For my primitive test environment, it appears that BitArray
is a bit faster, but is on the same order of magnitude as doing it yourself with an integral type. Also tested was a bool[]
, which was unsurprisingly the fastest. Accessing single bytes in memory is going to be less complex than accessing individual bits in different bytes.
Testing with 10000000 operations:
A UInt32 bitfield took 808 ms.
A BitArray (32) took 574 ms.
A List<bool>(32) took 436 ms.
Code:
class Program
{
static void Main(string[] args)
{
Random r = new Random();
r.Next(1000);
const int N = 10000000;
Console.WriteLine("Testing with {0} operations:", N);
Console.WriteLine(" A UInt32 bitfield took {0} ms.", TestBitField(r, N));
Console.WriteLine(" A BitArray (32) took {0} ms.", TestBitArray(r, N));
Console.WriteLine(" A List<bool>(32) took {0} ms.", TestBoolArray(r, N));
Console.Read();
}
static long TestBitField(Random r, int n)
{
UInt32 bitfield = 0;
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++) {
SetBit(ref bitfield, r.Next(32), true);
bool b = GetBit(bitfield, r.Next(32));
SetBit(ref bitfield, r.Next(32), b);
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
static bool GetBit(UInt32 x, int bitnum) {
if (bitnum < 0 || bitnum > 31)
throw new ArgumentOutOfRangeException("Invalid bit number");
return (x & (1 << bitnum)) != 0;
}
static void SetBit(ref UInt32 x, int bitnum, bool val)
{
if (bitnum < 0 || bitnum > 31)
throw new ArgumentOutOfRangeException("Invalid bit number");
if (val)
x |= (UInt32)(1 << bitnum);
else
x &= ~(UInt32)(1 << bitnum);
}
static long TestBitArray(Random r, int n)
{
BitArray b = new BitArray(32, false); // 40 bytes
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++) {
b.Set(r.Next(32), true);
bool v = b.Get(r.Next(32));
b.Set(r.Next(32), v);
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
static long TestBoolArray(Random r, int n)
{
bool[] ba = new bool[32];
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++) {
ba[r.Next(32)] = true;
bool v = ba[r.Next(32)];
ba[r.Next(32)] = v;
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
}
这篇关于是BitArray在C#中更快得到一个位值不是一个简单的一起选择按位转移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!