搜索了一下,但我并没有真正找到我所寻找的东西。
我必须每秒验证大约100个字节[16384](+许多其他任务......)。看起来蠢蠢欲动的最大问题是速度。
你们知道C#.NET中的任何好的校验和算法都非常快吗?它不一定非常精确,但如果一个位发生变化,校验和应该(通常......)也会发生变化。
字节存储在内存中,所以没有IO的东西可以减慢它的速度。
谢谢!
答案 0 :(得分:4)
扩展C.Evenhuis的答案,这里的一些变化应该快得多。我不确定他们的正确性,任何有点小小经验的人都想帮助我吗?我知道他们没有提供与每字节一样的校验和,但我确实认为他们给出的校验和是 good (不是非常,但显然足够)作为每字节的校验和。
正如我在评论中所说的那样,你可以通过不比较每字节字节来提高速度,但是将数组视为小数组的4倍,或者长度小8倍。将其视为long[]
仅在64位上提供了性能优势。
static unsafe uint ChecksumInt(byte[] array)
{
unchecked
{
uint checksum = 0;
fixed (byte* ptr = array)
{
var intPtr = (uint*)ptr;
var iterations = array.Length / 4;
var remainderIterations = array.Length % 4;
for (var i = 0; i < iterations; i++)
{
var val = intPtr[i];
checksum += val;
}
while (remainderIterations >= 0) // no more than 3 iterations
{
checksum += ptr[array.Length - remainderIterations];
remainderIterations--;
}
return checksum;
}
}
}
static unsafe ulong ChecksumLong(byte[] array)
{
unchecked
{
ulong checksum = 0;
fixed (byte* ptr = array)
{
var intPtr = (ulong*)ptr;
var iterations = array.Length / 8;
var remainderIterations = array.Length % 8;
for (var i = 0; i < iterations; i++)
{
var val = intPtr[i];
checksum += val;
}
while (remainderIterations >= 0) // no more than 7 iterations
{
checksum += ptr[array.Length - remainderIterations];
remainderIterations--;
}
return checksum;
}
}
}
我在64位(Core 2 Duo 3 GHz)上的性能测量结果,包含超过10,000次迭代的100,000个项目:
快得多。
但是,就像我说的那样,我不确定这是否提供了同样好的校验和。
答案 1 :(得分:1)
如果每个单位都很重要,则校验和算法必须处理每个字节。一个简单的算法就是简单地添加每个值并忽略溢出:
static unsafe uint GetChecksum(byte[] array)
{
unchecked
{
uint checksum = 0;
fixed (byte* arrayBase = array)
{
byte* arrayPointer = arrayBase;
for (int i = array.Length - 1; i >= 0; i--)
{
checksum += *arrayPointer;
arrayPointer++;
}
}
return checksum;
}
}
当然,您可能无法检测到所有更改并获得重复项,但它可能会为您提供快速算法执行方式的指示。