AFAIK, the difference is that memcpy is a 100% run-time call: memcpy does not know the size of the thing to be copied, nor the source/destination addresses. This makes it inherently slower. It has to do a lot of run-time checking, and must implement a copy loop.

By comparison a (non-elaborate) an opAssign is a straight up *assembly* memcopy: the compiler knows at all (most) the parameters at compile time: the source, and the size. This means the call is just replaced by an assembly copy.

Also: memcpy is neither safe nor CTFE-able.