0

我已经看到在 memmove 和 memcpy 之间有什么区别?它说memmove might be very slightly slower than memcpy

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

4

3 回答 3

5

来自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 程序员,你会做你期望工会做的事情。

于 2017-07-07T08:47:06.630 回答
2

std::memmove“可能”(强调)慢一点,std::memcpy因为它必须首先检查源范围和目标范围是否重叠。在内部,这只是几个指针比较;完成后,如果没有重叠或目标从源下方开始,它会调用std::memcpy; std::memcpy否则,它会从结尾向开头调用该副本的变体。

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

于 2017-07-07T12:11:11.800 回答
0

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

因此,如果您尝试使用 memcpy 将字符串abcd从某个位置复制XX+2,则可能会得到这样的结果

X: A B C D

在 memcpy 之后

X+2 A B A A

而 memmove 将向您保证不会丢失任何内容,因为它使用中间缓冲区来存储原始字符串。

另一方面,您可以restrict对源和目标使用限定符,这样您可以告诉 memmove 源和目标不重叠,并且如果您使用此限定符,memmove 可以选择其他更快的算法。

有关详细信息,请参见此处

于 2017-07-07T16:20:36.353 回答