Используя битовую манипуляцию, вы можете вычислить среднее значение байтов параллельно:
ulong NOLOW = 0xfefefefefefefefe;
unsafe {
//Add 8 bytes at a time, taking into account overflow between bytes
fixed (byte* pbBytes = &bytes[0])
fixed (byte* pbBytes2 = &bytes2[0])
fixed (byte* pbAns2 = &ans2[0]) {
ulong* pBytes = (ulong*)pbBytes;
ulong* pBytes2 = (ulong*)pbBytes2;
ulong* pAns2 = (ulong*)pbAns2;
for (int i = 0; i < Len; i++) {
pAns2[i] = (pBytes2[i] & pBytes[i]) + (((pBytes[i] ^ pBytes2[i]) & NOLOW) >> 1);
}
}
}
Я изменил код для хранения в отдельном массиве байтов ans
, так как мне нужны исходные массивы для сравнениядва метода.Очевидно, что вы можете сохранить исходное значение bytes[]
, если хотите.
Это основано на следующей формуле: x+y == (x&y)+(x|y) == (x&y)*2 + (x^y) == (x&y)<<1 + (x^y)
, что означает, что вы можете вычислить (x+y)/2 == (x&y)+((x^y) >> 1)
.Поскольку мы знаем, что мы вычисляем 8 байтов за раз, мы можем замаскировать бит младшего разряда из каждого байта, поэтому мы сдвигаем бит 0 для старшего бита каждого байта, когда мы сдвигаем все 8 байтов.
На моем ПК это работает в 2–3 раза быстрее (в 2 раза для более длинных массивов), чем сумма (в байтах).