1). var bitValue = (byteValue & (1 << bitNumber)) != 0;
2). using System.Collections.BitArray
with a Get(int index)
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 abyte
will hold only 8,int
only 32, etc. This is going to be the biggest difference between the two.Also,
BitArray
implementsIEnumerable
, where a integral type obviously does not. So it all depends on the requirements of your project; if you need anIEnumerable
or array-like interface, then go with theBitArray
.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. TBitArray
orbitfield
will use approximately 1/8th the space of abool[]
because they "pack" 8 boolean values into a single byte, whereas abool
by itself will take up the whole 8-bit byte. The space advantage of using a bitfield orBitArray
isn't going to matter though until you being storing lots ofbools
. (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 abool[]
, which was unsurprisingly the fastest. Accessing single bytes in memory is going to be less complex than accessing individual bits in different bytes.Code:
@Jonathon Reinhart,
your benchmark is unfortunately inconclusive. It does not take into account the effects of possible lazy-loading, caching and/or prefetching (by the CPU, the host OS and/or the .NET runtime).
Shuffle the order of the tests (or call the test methods multiple times) and you might notice different time measurments.
I did your original benchmark built with "Any CPU" platform target and .NET 4.0 client profile, running on my machine with a i7-3770 CPU and 64-bit Windows 7.
What i got was this:
which is pretty much in line with your observations.
However, executing the BitArray test before the UInt32 test yielded this:
By looking at the times for the UInt32 and BitArray tests you will notice that the measured time does not seem to be connected to the tests themselves, but rather to the order in which the tests are run.
To alleviate these side effects at least a little bit, i executed the test methods twice in each program run with the following results.
Test order UInt32, BitArray, BoolArray, UInt32, BitArray, BoolArray:
Test order BitArray, UInt32, BoolArray, BitArray, UInt32, BoolArray:
Looking at the second invocations of the test methods, it appears that at least on i7 CPUs with up-to-date .NET runtime, the UInt32 test is faster than the BitArray test, while the BoolArray test is still being the fastest.
(I apologize that i had to write my response to Jonathon's benchmark as an answer, but as a new SO user i am not allowed to comment...)
EDIT:
Instead of shuffling the order of test methods, you might try putting a Thread.Sleep(5000) or similar right before calling the first test...
Also the original test seems to put the UInt32 test at disadvantage, because it includes a boundary check "if (bitnum < 0 || bitnum > 31)", which is executed 30 million times. None of the other two tests include such a boundary check. However, this is actually not the whole truth, since both the BitArray and the bool array do boundary checks internally.
Although i didn't test, i expect that eliminating the boundary checks will make the UInt32 and BoolArray tests perform similarly, but that would not be a good proposition for a public API.