memmove的性能与memcpy相比两次?

时间:2017-07-07 08:38:44

标签: c++ c memcpy memmove

我已经看到What is the difference between memmove and memcpy?中接受的答案中指出的差异,它说memmove might be very slightly slower than memcpy

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

3 个答案:

答案 0 :(得分:4)

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

  

尽管被指定"好像"使用临时缓冲区,此函数的实际实现不会产生双重复制或额外内存的开销。对于小计数,它可能会加载和写出寄存器;对于较大的块,一个常见的方法(glibc和bsd libc)是从缓冲区的开头向前复制字节,如果目标在源之前开始,则从末尾开始向后复制,然后在那里回退到std :: memcpy完全没有重叠。

因此,所有可能性的开销是几个条件分支。对于大块,几乎不值得担心。

然而,值得记住的是union { float a; int b; } u; u.a = 10.0; int x = u.b; 是一种魔法'函数,是在两种不同类型之间进行投射的唯一合法方式。

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

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

这是合法的:

{{1}}

如果你是一名C程序员,你做联盟要做的事情。

答案 1 :(得分:2)

std::memmove"可能非常轻微慢于std::memcpy" (强调添加)因为它必须首先检查源和目标范围是否重叠。在内部,这只是几个指针比较;完成后,如果没有重叠或目标从源头下方开始,则调用std::memcpy;否则,它会调用std::memcpy的变体,从末尾向开头复制。

简而言之,唯一的区别在于初始比较;一旦完成,它就像std::memcpy一样。无需额外的缓冲区并将所有内容复制两次。

答案 2 :(得分:0)

Memcpy通常更快,因为它不会假设目的地和来源可能重叠。

因此,如果您尝试使用memcpy将字符串abcdX位置复制到X+2,则可能会得到类似的结果

X: A B C D

在memcpy之后

X+2 A B A A

而memmove会保证你不会丢失任何东西,因为它使用一个中间缓冲区来存储原始字符串。

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

有关详细信息,请参阅here