En general, el peor de los escenarios será en una compilación de depuración no optimizada donde memcpy
no está en línea y puede realizar comprobaciones adicionales de cordura/afirmación que ascienden a un pequeño número de instrucciones adicionales frente a un ciclo for.
Sin embargo, memcpy
está generalmente bien implementado para aprovechar cosas como intrínsecos, etc., pero esto variará con la arquitectura y el compilador de destino. Es poco probable que memcpy
sea peor que una implementación for-loop.
La gente a menudo tropiezan con el hecho de que los tamaños de establecimiento de memoria en bytes, y escriben cosas como éstas:
// wrong unless we're copying bytes.
memcpy(myGlobalArray, nums, numNums);
// wrong if an int isn't 4 bytes or the type of nums changed.
memcpy(myGlobalArray, nums, numNums);
// wrong if nums is no-longer an int array.
memcpy(myGlobalArray, nums, numNums * sizeof(int));
Puede protegerse aquí mediante el uso de las características del lenguaje que le permiten hacer un cierto grado de reflexión, que es : hacer las cosas en términos de los datos en sí en lugar de lo que sabe acerca de los datos, ya que en una función genérica por lo general no sabe nada acerca de los datos:
void foo (int[] nums, size_t numNums)
{
memcpy(myGlobalArray, nums, numNums * sizeof(*nums));
}
Tenga en cuenta que no desea que el " & "delante de" myGlob alArray "porque las matrices decaen automáticamente en punteros; en realidad estaba copiando "nums" a la dirección en la memoria donde se estaba reteniendo el puntero al myGlobalArray [0].
Uso memcpy
en objetos puede ser peligroso, tenga en cuenta:
struct Foo {
std::string m_string;
std::vector<int> m_vec;
};
Foo f1;
Foo f2;
f2.m_string = "hello";
f2.m_vec.push_back(42);
memcpy(&f1, &f2, sizeof(f2));
Este es el camino equivocado para copiar objetos que no son POD (datos llanura de edad). Tanto f1 como f2 ahora tienen std :: string que cree que posee "hola". Uno de ellos va a bloquearse cuando se destruct, y los dos se creen los dueños del mismo vector de enteros que contiene 42.
La mejor práctica para los programadores de C++ es utilizar std::copy
:
std::copy(nums, nums + numNums, myGlobalArray);
Esto puede tome decisiones sobre el tiempo de compilación sobre qué hacer, incluido el uso de memcpy
o memmove
y, potencialmente, el uso de instrucciones SSE/vector si es posible. Otra ventaja es que si se escribe esto:
struct Foo {
int m_i;
};
Foo f1[10], f2[10];
memcpy(&f1, &f2, sizeof(f1));
y más tarde en el cambio de Foo para incluir un std::string
, su código se romperá. Si en lugar de escribir:
struct Foo {
int m_i;
};
enum { NumFoos = 10 };
Foo f1[NumFoos], f2[NumFoos];
std::copy(f2, f2 + numFoos, f1);
el compilador cambiar su código para hacer lo correcto sin ningún trabajo adicional para usted, y su código es un poco más fácil de leer.
¿Has intentado compilar tus ejemplos? –
duplicado posible de [¿Por qué es memcpy() y memmove() más rápido que los incrementos puntero?] (Http://stackoverflow.com/questions/7776085/why-is-memcpy-and-memmove-faster-than-pointer-increments) Aunque esto no menciona más rápido, ambos fragmentos son funcionalmente correctos, por lo que se reducirá a eso. –