2012-02-07 21 views
11

Como parece, placement new crea un objeto nuevo en una memoria preasignada, ¿significa que tomaría menos tiempo? Parece que es más rápido que asignar usando el antiguo ordinario new. Entonces, si esto es tan conveniente y más rápido, ¿por qué no usar placement new todo el tiempo?¿Por qué debería usar la ubicación nueva?

+4

Esto podría ayudar: http://www.parashift.com/c++faq-lite/dtors.html#faq-11.10 –

+0

La ubicación nueva no es solo para controlar la ubicación de los objetos, también se puede usar para una tonelada de depuración de bajo nivel (el CRT de depuración lo usa para rastrear asignaciones y detectar y rastrear fugas). – ssube

+1

@ron - ¿Qué sucede si no tiene memoria preasignada? –

Respuesta

4

la normales (nonplacement) new es básicamente lo mismo que hacer

T* ptr = static_cast<T*>(malloc(sizeof(T))); 
new(ptr) T; 

Por supuesto, la realidad se ve un poco diferente debido a errorchecking y tal, pero el resultado es más o menos lo mismo (a través de no idéntico, no puede delete un puntero asignado de esa manera, en su lugar debe llamar al destructor explícitamente (ptr->~T()) y luego liberar la memoria usando free).

Por lo tanto, la colocación nueva debería ser más rápida que la no colocación nueva, ya que no es necesario asignar la memoria. Sin embargo, el problema es que la memoria debe asignarse en algún lugar. Entonces, esencialmente ha reemplazado una llamada al new con una llamada al placement new y algún código para la asignación en algún lugar (de no ser así, ¿por qué usaría new en primer lugar?).Debería ser obvio que esto es menos conveniente y más propenso a errores.

Ahora, por supuesto, puede escribir un método de asignación más rápido, pero para eso normalmente necesita hacer algún tipo de compensación. No será fácil escribir un asignador que sea más rápido sin usar más memoria (datos adicionales para una identificación más rápida de bloques libres) o hacerlo muy específico (escribir una asignación rápida de un solo objeto es mucho más fácil que una general). Al final, por lo general, no vale la pena el esfuerzo (para situaciones en las que vale la pena el esfuerzo, probablemente ya se haya realizado, por lo que podría usar un asignador existente (que probablemente utiliza la ubicación nueva internamente)).

Hay, por supuesto utiliza para la colocación de nuevo (a veces usted tiene preasignada la memoria), pero que simplemente no es el caso común

+0

http://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-vs-new/7970036#7970036 – Flexo

+0

@awoodland: ¿Su punto es qué exactamente? – Grizzly

+0

mi punto es que casi se puede reinventar 'nuevo' usando la colocación' new' + 'malloc' – Flexo

2

Uno de los propósitos de la ubicación nueva es utilizar un asignador personalizado para crear objetos nuevos y llamar a sus constructores. No siempre es más rápido, porque es tan rápido como su asignador personalizado.

+2

Es necesario en el caso de un asignador personalizado y tiene una clase que necesita que se invoque el constructor. Me encontré con una situación en un proyecto en el que teníamos que usar el asignador personalizado, que acababa de devolver trozos de memoria del tamaño adecuado, y el objeto que necesitaba asignar tenía miembros que HABÍAN sido inicializados en el constructor –

3

Simplemente no es necesario para la mayoría de los programas ya que sus patrones de uso no lo hacen necesario. No hace ninguna diferencia para los programas que no usan tanto el montón y es difícil hacerlo bien (mejor que su sistema operativo, eso es). También puede ganar mucho optimizando su asignación. En su mayor parte, cualquier optimización algorítmica dará como resultado una aceleración general mucho más grande. Muchas de las garantías que un asignador personalizado puede ofrecer (límites de tiempo garantizados para la asignación a través de memoria preasignada, baja fragmentación de memoria) a menudo no son necesarias.

Definitivamente hay programas que pueden beneficiarse de la gestión de la memoria por sí mismos, son difíciles de identificar. Después de haber encontrado que la asignación de memoria es en realidad un cuello de botella, es aún más difícil encontrar un mejor esquema de asignación. Cuando todo está hecho, a menudo todavía no vale la pena la molestia.

+0

¿Sería el votante recesivo? tan amable de explicarse a sí mismo? Intenté dar una respuesta equilibrada a lo que el OP realmente ha pedido. Tal vez no estoy familiarizado con otra gran razón para no usar 'placement new'. – pmr

+0

Presumiblemente porque 1) esto en realidad no responde la pregunta, 2) el afiche no indicó su caso de uso, pero si preguntan al respecto, ¿por qué no educarlos? y 3) el sistema operativo está construido para el caso general; la colocación nueva permite que programas específicos implementen asignadores ideales para su uso específico. Dar un general "probablemente sea innecesario" no es útil a menos que se combine con una respuesta real. – jzila

+0

@jzila Tengo la impresión de que OP está preguntando sobre el caso general: ¿por qué la colocación nueva no se usa con tanta frecuencia? Intenté poner más énfasis en diferentes dominios en la edición. – pmr

2

La ubicación nueva utilizada para colocar un objeto en un lugar determinado de la memoria puede llevar menos tiempo, porque de hecho se evita asignar memoria en este paso.

Sin embargo, debe haber sido asignado en algún momento antes de lo cual probablemente lleva tiempo. Tiene sentido usarlo si realmente tiene una razón para colocar el objeto en la memoria preasignada.

No es un uso único de este tipo de nuevo operador. Más detalles here.

Además, recuerde que la colocación nueva no llama al destructor automáticamente. Tienes que hacer foo->~Foo(); para tu Foo foo; manualmente.

1

El único lugar que he encontrado donde la ubicación nueva hará que tus asignaciones sean mucho más rápidas es si tienes un gran número de objetos del mismo tamaño que tienen vidas limitadas, causando que se asignen y destruyan con frecuencia. Si no puede garantizar este tipo de comportamiento, probablemente sea mejor que use la nueva implementación predeterminada.

1

Las aplicaciones que necesitan una gran cantidad del mismo objeto de tamaño a menudo se puede ver a una velocidad mayor desde la asignación del pool (o bulk) Básicamente asignaría un gran búfer (o página) para lotes de ese objeto, y luego llamará a la colocación nueva dentro de él cuando se solicite el objeto. Si bien esto puede acelerar mucho las cosas, no es realmente necesario para la mayoría de los programas.

Intentar hacer esto para los programas que realmente no lo necesitan probablemente solo le dará una aceleración mínima, pero podría costarle muchas horas en la depuración.

Así que realmente mira lo que necesitas; si está asignando una tonelada del mismo objeto, sí, la colocación nueva podría ser más rápida. ¿Pero solo unos pocos objetos? No me molestaría.

No siempre es una cuestión de tiempo. Por ejemplo, puede usar la colocación nueva para garantizar la alineación de sus objetos en el montón. Usted puede hacer algo como:

void* buffer = aligned_malloc(sizeof(Object), 16); 
Object* object = new (buffer) Waypoint(); 

Esto es necesario para algunos tipos, tales como matrices de flotador para ser utilizado con las funciones y los registros de la ESS.

Cuestiones relacionadas