有没有办法比较两块内存,并知道它们在哪一点上不同(memcmp()不符合这个要求)?我不想执行昂贵的循环。提前谢谢。
此致,Neo_b
答案 0 :(得分:4)
std::mismatch将为您std::distance提供此功能。
答案 1 :(得分:2)
与你正在做的其他事情相比,循环很便宜:首要的成本是从ram(或磁盘!)中检索数据。
答案 2 :(得分:2)
您无法避免使用超过几个字节的内存比较进行循环。编写你能想象到的算法。这很简单,你可能会惊讶于编译器如何优化这样的代码。
答案 3 :(得分:2)
memcmp简单地执行“代价高昂的循环”,字节为字节。例如,这是Microsoft的实现:
EXTERN_C int __cdecl memcmp(const void *Ptr1, const void *Ptr2, size_t Count)
{
INT v = 0;
BYTE *p1 = (BYTE *)Ptr1;
BYTE *p2 = (BYTE *)Ptr2;
while(Count-- > 0 && v == 0) {
v = *(p1++) - *(p2++);
}
return v;
}
大多数其他实现都完全相同。根据您的需要,您可以这样做:
long my_memcmp(const void *Ptr1, const void *Ptr2, size_t Count)
{
INT v = 0;
long pos = 0;
BYTE *p1 = (BYTE *)Ptr1;
BYTE *p2 = (BYTE *)Ptr2;
while(Count-- > 0 && v == 0)
{
v = *(p1++) - *(p2++);
if (v == 0)
pos++;
else
break;
}
return pos;
}
答案 4 :(得分:1)
如果有更好的方法来比较两块内存,memcmp将会重新实现。
经常这么说,memcmp在标准C库中有一个默认的可移植实现,但是编译器本身经常将它作为内置函数实现。这个内置函数应该针对目标体系结构进行高度优化。因此,可以使用少量盐来实现库实现。
答案 5 :(得分:0)
你总是需要一个循环。但是你可以测试循环4个字节(强制转换为int *)或8个字节(uint64_t
或long long int
)是否比天真的每字节解决方案快。
更好的是,根据长度(例如,> 1kb),您可以展开循环,这意味着您可以检查每8个int / uint64_t,并且在不匹配时精确定位第一个不同的字节。
uint64_t *bigsteps1 = (uint64_t*)m1;
uint64_t *bigsteps2 = (uint64_t*)m2;
int steps = min(m1_len,m2_len)/sizeof(uint64_t);
int i;
for ( i=0; i<steps; i+=8 )
{
if ( bigsteps1[i] != bigsteps2[i]
|| bigsteps1[i+1] != bigsteps2[i+1]
/// ....
|| bigsteps1[i+7] != bigsteps2[i+7] ) break;
}
// i<steps tells if we found a difference
// end game is trivial, left as an excercise to the reader.
循环展开也可能适得其反,因为你有所有这些+ N的东西,而且i + = 8。基准确定。
ps 还检查内存对齐方式:m1&0xff == m2&0xff == 0