我已经看到What is the difference between memmove and memcpy?中接受的答案中指出的差异,它说memmove might be very slightly slower than memcpy
。
我们可以通过以下方式实现memmove
的替代方案:分配临时缓冲区,然后memcpy
两次(src - > tmp,tmp - > dest)。我的问题是:哪种方式更快,memmove
还是替代?
答案 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将字符串abcd
从X
位置复制到X+2
,则可能会得到类似的结果
X: A B C D
在memcpy之后
X+2 A B A A
而memmove会保证你不会丢失任何东西,因为它使用一个中间缓冲区来存储原始字符串。
另一方面,您可以使用限定符restrict
作为源和目标,并且像这样您可以告诉memmove源和目标不重叠,并且像memmove可以选择其他更快的算法你使用这个限定符的情况。
有关详细信息,请参阅here。