2017-07-07 196 views
0

我看到What is the difference between memmove and memcpy?中接受的答案中指出的差异,它表示memmove might be very slightly slower than memcpymemmove与memcpy比较两次的性能?

我们可以通过如下方式实现memmove的替代方案:分配一个临时缓冲区,然后memcpy两次(src - > tmp,tmp - > dest)。我的问题是:哪种方式更快,memmove还是替代方法?

+0

这取决于目标机器和实现。 –

+4

复制数据很慢。复制数据*两次*会变慢。 'memmove' *可能会比'memcpy'慢,因为它能够处理重叠的内存,但是'memmove'仍然只能复制一次数据*。 –

+1

在您对时间感兴趣的平台上对其进行剖析。然而,你写一个比memmove更好的memmove的机会似乎不大可能。 – xaxxon

回答

4

http://en.cppreference.com/w/cpp/string/byte/memmove

尽管被指定为“好像”使用临时缓冲区,这个功能的实际实现不承担双重复印或额外内存的开销。对于小数值,它可能会加载并写出寄存器;对于较大的块,一种常用的方法(glibc和bsd libc)是如果目的地在源之前开始,则从缓冲区的开始向前复制字节,否则从结尾向后,当存在时回退到std :: memcpy根本没有重叠。

因此,所有可能性的开销都是一对条件分支。非常值得担心大块。

但值得记住的是std::memcpy是一个'魔术'功能,是两种不同类型之间唯一合法的投射方式。

在C++中,这是非法的(未定义行为):

union { 
    float a; 
    int b; 
} u; 

u.a = 10.0; 
int x = u.b; 

这是合法的:

float a = 10.0; 
int b; 
std::memcpy(std::addressof(b), std::addressof(a), size(b)); 

,并做你所期望的工会做什么,如果你是一个C程序员。

1

std::memmove“可以是比std::memcpy非常轻微慢”(强调),因为它必须首先检查源和目标范围是否重叠。在内部,这只是一对指针比较;如果没有重叠或者目标在源代码下面开始,它会调用std::memcpy;否则,它会调用std::memcpy的变体,从末尾开始复制。

总之,有只有区别在于初步比较;一旦完成,就像std::memcpy。不需要额外的缓冲区并将所有内容复制两次。

0

Memcpy通常更快,因为它不认为目标和源可能重叠。

所以,如果你尝试使用memcpy字符串abcd从位置X复制到X+2有可能得到的结果类似的memcpy

X+2 A B A A 

同时的memmove

X: A B C D 

后将保证你没有丢失任何东西,因为它使用中间缓冲区来存储原始字符串。

在另一方面,你可以使用限定restrict的来源和目的地,这样你可以告诉的memmove源和目标不重叠,并且像的memmove可能的情况下,你用选择其他更快的算法这个限定词。

详情请参阅here