¿Existen limitaciones prácticas para usar solo std :: string en lugar de matrices de caracteres y std :: vector / list en lugar de matrices en c ++?

StackOverflow https://stackoverflow.com/questions/801385

Pregunta

Uso vectores, listas, cadenas y cadenas obsesivamente en mi código. ¿Hay algún retén 22s involucrado que debería hacerme más interesado en usar arreglos de vez en cuando, en su lugar, en caracteres y en wchars?

Básicamente, si trabajar en un entorno que admita la biblioteca de plantillas estándar, ¿hay algún caso en el que usar los tipos primitivos sea realmente mejor?

¿Fue útil?

Solución

Para el 99% del tiempo y para el 99% de las implementaciones de la Biblioteca estándar, encontrará que std :: vectors será lo suficientemente rápido, y la conveniencia y seguridad que obtiene al usarlos superará cualquier pequeño costo de rendimiento.

Para aquellos casos muy raros en los que realmente necesitas código simple, puedes tratar un vector como una matriz de estilo C:

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

El estándar C ++ garantiza que los vectores se asignan de forma contigua, por lo que se garantiza que esto funcione.

En cuanto a las cadenas, el factor de conveniencia se vuelve casi abrumador y los problemas de rendimiento tienden a desaparecer. Si le gustan las cadenas de estilo C, también volverá al uso de funciones como strlen (), que son inherentemente muy ineficientes.

En cuanto a las listas, debe pensarlo dos veces, y probablemente tres veces, antes de usarlas, ya sea su propia implementación o el estándar. La gran mayoría de los problemas informáticos se resuelven mejor utilizando un vector / array. Las listas de motivos que aparecen con tanta frecuencia en la literatura son en gran parte debido a que son una estructura de datos conveniente para que los redactores de libros de texto y cursos de capacitación utilicen para explicar los punteros y la asignación dinámica de una sola vez. Hablo aquí como ex redactor de cursos de formación.

Otros consejos

Me apegaría a las clases STL (vectores, cadenas, etc.). Son más seguros, más fáciles de usar, más productivos, con menos probabilidades de tener pérdidas de memoria y, AFAIK, realizan algunas comprobaciones adicionales de los límites en tiempo de ejecución, al menos en el momento de DEBUG (Visual C ++).

Luego, mide el rendimiento. Si identifica que el cuello (s) de botella está en las clases STL, entonces cambie a las cadenas de estilo C y al uso de matrices.

Desde mi experiencia, las posibilidades de tener un cuello de botella en el uso de vectores o cadenas son muy bajas.

Un problema es la sobrecarga al acceder a los elementos. Incluso con vector y cadena, cuando accede a un elemento por índice, primero necesita recuperar la dirección del búfer, luego agregar el desplazamiento (no lo hace manualmente, pero el compilador emite dicho código). Con la matriz en bruto ya tiene la dirección de búfer. Esta indirección adicional puede generar una sobrecarga significativa en ciertos casos y está sujeta a perfiles cuando desee mejorar el rendimiento.

Si no necesita respuestas en tiempo real, siga con su enfoque. Son más seguros que los caracteres.

Ocasionalmente, puede encontrar escenarios en los que obtendrá un mejor rendimiento o uso de la memoria al hacer algunas cosas usted mismo (por ejemplo, std :: string generalmente tiene unos 24 bytes de sobrecarga, 12 bytes para los punteros en el propio std :: string y un bloque de encabezado en su pieza asignada dinámicamente).

He trabajado en proyectos donde la conversión de std :: string a const char * guardó una memoria notable (10's de MB). No creo que estos proyectos sean lo que ustedes llamarían típicos.

Oh, usar STL dañará tus tiempos de compilación, y en algún momento eso puede ser un problema. Cuando su proyecto genere más de un GB de archivos de objetos que se pasan al vinculador, es posible que desee considerar la cantidad de eso de la plantilla.

He trabajado en varios proyectos donde la sobrecarga de memoria para cadenas se ha vuelto problemática.

Vale la pena considerar de antemano cómo debe escalar su aplicación. Si necesita almacenar un número ilimitado de cadenas, el uso de const char * en una tabla de cadenas administrada globalmente puede ahorrarle una gran cantidad de memoria.

Pero en general, definitivamente use los tipos STL a menos que haya una muy buena razón para hacer lo contrario.

Creo que la técnica de asignación de memoria predeterminada es un búfer para vectores y cadenas que asigna el doble de memoria cada vez que la memoria asignada actualmente se agota. Esto puede ser un desperdicio. Puede proporcionar un asignador personalizado, por supuesto ...

La otra cosa a considerar es la pila contra el montón. Las matrices y cadenas de tamaño estático pueden ubicarse en la pila, o al menos el compilador se encarga de la administración de la memoria por usted. Los compiladores más nuevos manejarán arreglos de tamaño dinámico para usted también si brindan la característica relevante C99 / C ++ 0x. Los vectores y las cadenas siempre usarán el montón, y esto puede introducir problemas de rendimiento si tiene restricciones muy estrictas.

Como regla general, use lo que ya existe a menos que afecte a su proyecto con su sobrecarga de velocidad / memoria ... probablemente encontrará que para el 99% de las cosas que proporcionó el STL las clases le ahorran tiempo y esfuerzo con poco o nada Impacto en el rendimiento de sus aplicaciones. (es decir, " evitar la optimización prematura ")

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top