¿Cuánto cuesta usar punteros inteligentes, en particular boost :: shared_ptr, más en comparación con los punteros en términos de tiempo y memoria? ¿El uso de punteros descubiertos es mejor para las partes de alto desempeño de los sistemas embebidos/integrados? ¿Recomendaría usar punteros simples o punteros inteligentes para componentes de rendimiento intensivo?C++ rendimiento de puntero inteligente
Respuesta
Desreferenciar punteros inteligentes suele ser trivial, sin duda para impulso en modo de lanzamiento. Todos los controles de impulso están en tiempo de compilación. (Los punteros inteligentes podrían, en teoría, hacer cosas inteligentes en los hilos). Esto aún deja muchas otras operaciones. Nicola mencionó construcción, copia y destrucción. Este no es el conjunto completo, sin embargo. Otras operaciones importantes son el intercambio, la asignación y el restablecimiento a NULL. Básicamente, cualquier operación que requiera inteligencia.
Tenga en cuenta que algunas de estas operaciones están excluidas por algunos punteros inteligentes. P.ej. boost::scoped_ptr
ni siquiera se puede copiar, y mucho menos asignar. Como esto deja menos operaciones, la implementación se puede optimizar para estos pocos métodos.
De hecho, con la próxima TR1, es bastante probable que los compiladores obtengan mejores resultados con los punteros inteligentes que con los punteros sin formato. P.ej. es posible que un compilador pueda probar que un puntero inteligente que no se puede copiar no tiene alias en algunas situaciones, simplemente porque no se puede copiar. Piénselo: el aliasing ocurre cuando se crean dos punteros apuntando al mismo objeto. Si no se puede copiar el primer puntero, ¿cómo un segundo puntero apunta hacia el mismo objeto? (Hay formas de evitarlo también: el operador * tiene que devolver un valor l)
Boost proporciona diferentes punteros inteligentes. En general, tanto la ocupación de la memoria, que varía de acuerdo con el tipo de puntero inteligente, y el rendimiento no deberían ser un problema. Para una comparación de rendimiento, puede consultar este http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smarttests.htm.
Como puede ver, solo se tienen en cuenta la construcción, la copia y la destrucción para comparar el rendimiento, lo que significa que quitarle un puntero inteligente tiene el mismo costo que un puntero sin formato.
el siguiente fragmento demuestra que no hay pérdida de rendimiento mediante el uso de un shared_ptr<>
en lugar de un puntero en bruto:
#include <iostream>
#include <tr1/memory>
int main()
{
#ifdef USE_SHARED_PTR
std::tr1::shared_ptr<volatile int> i(new int(1));
#else
volatile int * i = new int(1);
#endif
long long int h = 0;
for(long long int j=0;j < 10000000000LL; j++)
{
h += *i;
}
std::cout << h << std::endl;
return 0;
}
Los punteros inteligentes de referencia (el tipo más común) solo cuestan más cuando los copia, los crea y los elimina. Este costo adicional puede ser sustancial si está copiando mucho, porque la mayoría de ellos son seguros para subprocesos.
Si solo desea un puntero de "autodeleción", existe el auto_ptr muy difamado, o el nuevo y brillante (pero no mucho soporte aún) unique_ptr de C++ 0x.
La última vez que probé, con VC6, el compilador no pudo optimizar el código con un puntero inteligente tan bien como con un puntero sin formato. Las cosas podrían haber cambiado desde entonces.
La última vez que probé una versión anterior de boost (1.34 creo) con VC6, el compilador optimizó el incremento atómico del refcount para un weak_ptr. Eso hizo que las cosas funcionasen considerablemente más rápido, aunque causó bastantes cuelgues en las librerías enhebradas. – Michel
VC6 Me doy cuenta que todavía se usa mucho en proyectos grandes que no pueden cambiar fácilmente, pero seamos justos aquí, no fue un compilador maduro hasta VC2003, la segunda versión dentro del ciclo de vida del producto VS.NET. – ApplePieIsGood
La única manera de lidiar con los problemas de rendimiento es perfilar su código. La mayor parte de los problemas de rendimiento se imagina de todos modos; solo el perfil le indicará dónde se encuentran sus cuellos de botella.
Si resulta que el uso de punteros inteligentes produce un cuello de botella donde los punteros crudos no lo hacen, ¡utilice punteros crudos! Hasta entonces, no me preocuparía demasiado por eso; la mayoría de las operaciones en punteros inteligentes son razonablemente rápidas. Probablemente compares cadenas demasiado a menudo (o algo así) para que importen.
Hay una casa intermedia a menudo pasada por alto entre un std::vector<T*>
administrado "manualmente" (es decir, punteros sin formato) y un std::vector<boost::shared_ptr<T> >
, en la forma de las clases boost::ptr_container
.
Estos combinan el rendimiento de un contenedor de puntero sin procesar con la conveniencia de un contenedor de punteros inteligentes (es decir, proporcionan la funcionalidad que a las personas les gustaría contenedores STL de std::auto_ptr
para proporcionar, if that worked).
- 1. puntero inteligente Implementación en C
- 2. C++ puntero inteligente const correctness
- 3. regla de tres con puntero inteligente?
- 4. Copiar el constructor con el puntero inteligente
- 5. pimpl-idioma en la plantilla; qué puntero inteligente?
- 6. Plantilla de "puntero inteligente" de C++ que se convierte automáticamente en puntero descubierto pero no se puede eliminar explícitamente
- 7. ¿Es el mango lo mismo que un puntero inteligente?
- 8. ¿Puedo escribir un functor de C++ que acepte tanto un puntero sin formato como un puntero inteligente?
- 9. Puntero inteligente sopla pila debido a la eliminación recursiva
- 10. devolviendo un 'puntero' que se requiere para ser sostenido por un puntero inteligente
- 11. ¿Hay un puntero inteligente general como auto_ptr y shared_ptr que no necesita C++ 0x?
- 12. C: forma inteligente de "cambiar" una matriz?
- 13. C/C++ Puntero Pregunta
- 14. Mejoras en el rendimiento de C++ 0x
- 15. ¿El plural inteligente siempre inteligente?
- 16. Convertir del puntero C++/CLI al puntero nativo de C++
- 17. Puntero de función C#?
- 18. C++ asignación de puntero
- 19. C++ borrar un puntero a un puntero
- 20. Puntero a un puntero en objetivo-c?
- 21. C# función de puntero en función sobrecargada
- 22. (nil) puntero en C/C++
- 23. ¿Por qué las implementaciones de puntero inteligente de C++ mantienen el contador de referencia en el montón junto con el puntero?
- 24. ¿Cómo funciona el recuento de referencias de un puntero inteligente de recuento de referencias?
- 25. Llamar C++ puntero de función de C#
- 26. Algoritmo de paginación inteligente
- 27. C#: Puntero a duplicar
- 28. C puntero de función de conversión para anular puntero
- 29. elenco de puntero indirecto a un puntero de Objective-C
- 30. C Array/Puntero problema
Desafortunadamente, su idea de punteros inteligentes optimizados no funcionará, al menos en C++. Es posible que haya almacenado el puntero en otro lugar antes de colocarlo en el puntero inteligente. Además, es fácil (pero no aconsejable) sacar el puntero C sin procesar de un puntero inteligente, al hacer & * smart_ptr; –
estoy de acuerdo con chris jefferson. nadie le impide almacenarlo en otro lugar antes de ponerlo en el puntero inteligente –
He escrito una pequeña respuesta sobre alias aquí: http://stackoverflow.com/questions/270408/is-it-better-in-c-to- pass-by-value-or-pass-by-constant-reference # 271344 –