简体   繁体   中英

Performance of memmove compared to memcpy twice?

I have seen the difference pointed in the accepted answer in What is the difference between memmove and memcpy? and it said memmove might be very slightly slower than memcpy .

We can implement an alternative for memmove by doing as follows: allocate a temporary buffer, then memcpy twice (src -> tmp, tmp -> dest). My question is: which way is faster, memmove or the alternative?

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

Despite being specified "as if" a temporary buffer is used, actual implementations of this function do not incur the overhead of double copying or extra memory. For small count, it may load up and write out registers; for larger blocks, a common approach (glibc and bsd libc) is to copy bytes forwards from the beginning of the buffer if the destination starts before the source, and backwards from the end otherwise, with a fall back to std::memcpy when there is no overlap at all.

Therefore the overhead in all likelihood is a couple of conditional branches. Hardly worth worrying about for large blocks.

However, it is worth remembering that std::memcpy is a 'magic' function, being the only legal way to cast between two dissimilar types.

In c++, this is illegal (undefined behaviour):

union {
  float a;
  int b;
} u;

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

This is legal:

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

and does what you'd expect the union to do if you were a C programmer.

std::memmove "may be very slightly slower than std::memcpy " (emphasis added) because it has to first check whether the source and target ranges overlap. Internally, that's just a couple of pointer comparisons; having done that, if there's no overlap or the target starts below the source, it calls std::memcpy ; otherwise, it calls a variant of std::memcpy that copies from the end toward the beginning.

In short, there only difference is that initial comparison; once that's done, it's just like std::memcpy . No need for that extra buffer and copying everything twice.

Memcpy is generally faster as it does not suppose that the destination and source could overlap.

So, if you try and use memcpy to copy the string abcd from a location X to X+2 it is possible to get a result like that

X: A B C D

after memcpy

X+2 A B A A

while memmove will guaratee you that nothing is lost, because it uses an intermediate buffer to store the original string.

On the other hand, you can use the qualifier restrict for the source and destination and like this you can tell memmove that the source and the destination are not overlapped, and like that memmove could choose other faster algorithm in case you use this qualifier.

For details see here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM