[英]How to Compare two BitArray and return indices of differences from second array
我有兩個BitArray
對象。 並想檢查值是否與第一個BitArray
比較然后返回第二個數組的索引。 我嘗試遍歷每個位,但是這花費了太多時間,即:我有以下兩個對象:
BitArray a = new BitArray{true,false,true};
BitArray b = new BitArray{false,false,false};
並希望返回結果0,2,因為BitArray b與BitArray a相比有兩個變化。
如果性能是這里的主要目標,那么您將不會使用BitArray
; 這種抽象根本不是最優的。 您可能希望放置到自己的超大整數緩沖區,在每個緩沖區上使用“ xor”來計算增量,然后對增量使用位運算(xor結果)。
但是,在.NET Core 3上,您可以直接訪問x86指令集,從而為我們提供了SIMD和popcnt。 我們可以在這里使用SIMD XOR然后在三角洲上使用popcnt很好地結合這些東西(沒有SIMD popcnt AFAIK,但是我們可以手動展開):
// make sure these are multiples of 128-bit, so: 4; otherwise
// you'll have to deal with the leftover bits manually
uint[] left = new uint[16], right = new uint[16];
Random rand = new Random(12345);
for (int i = 0; i < left.Length; i++)
left[i] = (uint)rand.Next();
for (int i = 0; i < right.Length; i++)
right[i] = (uint)rand.Next();
// real(ish) code starts here
// loop over our `uint[]` as spans of Vector128<uint>
var lspan = MemoryMarshal.Cast<uint, Vector128<uint>>(left);
var rspan = MemoryMarshal.Cast<uint, Vector128<uint>>(right);
uint count = 0;
for(int i = 0; i < lspan.Length; i++)
{
// compute the bit delta
var delta = Popcnt.Xor(lspan[i], rspan[i]);
// Vector128 is 4xUInt32, so: unroll
count += Popcnt.PopCount(delta.GetElement(0))
+ Popcnt.PopCount(delta.GetElement(1))
+ Popcnt.PopCount(delta.GetElement(2))
+ Popcnt.PopCount(delta.GetElement(3));
}
Console.WriteLine(count);
您也可以對xor使用更通用的Vector<T>
(它也可以在.NET Framework上運行,並且可以處理比128更寬的大小),但是:那時沒有直接的popcount; 例:
// loop over our `uint[]` as spans of Vector<uint>
var lspan = MemoryMarshal.Cast<uint, Vector<uint>>(left);
var rspan = MemoryMarshal.Cast<uint, Vector<uint>>(right);
for(int i = 0; i < lspan.Length; i++)
{
// compute the bit delta
var delta = lspan[i] ^ rspan[i];
// work with delta...
}
該( Vector<T>
)通常使您的SIMD寬度為256,甚至可能為512。
如果位數組的元素計數相同,則可以使用以下代碼-
IList<int> differentIndices = new List<int>();
for(int i=0;i<a.Count;i++)
{
if (a[i] ^ b[i])
{
differentIndices.Add(i);
}
}
只需使用XOR操作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.