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?
Respuesta
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
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.
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 –
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.
¿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
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
@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
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.
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.
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.
- 1. ¿Por qué debería usar MXML?
- 2. ¿Por qué debería usar @properties?
- 3. ¿Por qué debería usar Flex?
- 4. ¿Por qué debería usar "aplicar"?
- 5. ¿Por qué debería usar Drools?
- 6. ¿Por qué debería usar glBindAttribLocation?
- 7. ¿Por qué debería aprender y usar puntales?
- 8. ¿Por qué debería usar exit select?
- 9. ¿Por qué debería usar un CAAnimationGroup?
- 10. ¿Cuándo y por qué debería usar TStringBuilder?
- 11. ¿Por qué debería evitar usar el Dispatcher?
- 12. ¿Por qué no debería usar Unity?
- 13. EF4.1 POCO: Por qué debería usar ICollection
- 14. ¿Por qué debería usar Spring Android?
- 15. ¿Por qué no debería usar AutoDual?
- 16. ¿Por qué debería usar 'aplicar' en Clojure?
- 17. ¿Por qué debería usar Doctrine sobre Zend_Db?
- 18. ¿Por qué no debería usar UNIVERSAL :: isa?
- 19. ¿Puedo usar la ubicación nueva (this) en operator =?
- 20. ¿Por qué no debería usar iguales con la herencia?
- 21. ¿Por qué debería usar MVVM en la aplicación Silverlight?
- 22. C# Logging. ¿Qué debería usar?
- 23. ¿Por qué debería/no debería usar el operador "nuevo" para instanciar una clase, y por qué?
- 24. ¿Qué Python debería usar?
- 25. Por qué * debería * usamos EventHandler
- 26. ¿Por qué debería usar Desarrollo controlado por características?
- 27. ¿Qué IronPython IDE debería usar?
- 28. ¿Qué GWT EventBus debería usar?
- 29. ¿Qué paquete postgresql debería usar?
- 30. ¿Por qué se debería usar "git merge -s ours"?
Esto podría ayudar: http://www.parashift.com/c++faq-lite/dtors.html#faq-11.10 –
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
@ron - ¿Qué sucede si no tiene memoria preasignada? –