2010-07-06 7 views
30

Uso frecuentemente los contenedores STL pero nunca he usado los algoritmos STL que se usarán con los contenedores STL.¿Cuándo deberían usarse los algoritmos STL en lugar de usar los propios?

Una de las ventajas del uso de los algoritmos STL es que proporcionan un método para eliminar bucles de modo que se reduce la complejidad de la lógica del código. Hay otros beneficios que no mencionaré aquí.

Nunca he visto el código C++ que utiliza los algoritmos STL. Desde el código de muestra dentro de los artículos de la página web hasta los proyectos de código abierto, no he visto su uso.

¿Se usan con más frecuencia de lo que parece?

+2

"No he visto su uso" - ¿eh? Estoy sorprendido. No puedo darte contraejemplos fuera de mi cabeza, pero STL definitivamente está ahí + una de las mejores bibliotecas alrededor. –

+0

No puedo recordar la última vez que vi un programa considerable de C++ _sin_ al menos un algoritmo STL. Heck, 'std :: sort' solo se usa en el 90% de los programas que no son de juguete – MSalters

+1

Debería ver nuestro código. Millones de líneas de C++ y ni una pizca de stl en cualquier lugar cercano. Sin embargo, estábamos desarrollando C++ cuando el stl era solo un sueño, y las plantillas eran mal compatibles con los escritores de tehcompiler. En el momento en que la stl se hizo adecuada para nuestro propósito, habíamos estado utilizando nuestro propio equivalente laminado durante varios años. Para nosotros no es necesario usar otra implementación de una cadena, vector o clase de lista. – lilburne

Respuesta

70

Respuesta corta: Siempre.

Respuesta larga: Siempre. Para eso están allí. Están optimizados para su uso con contenedores STL, y son más rápidos, claros y más idiomáticos que cualquier cosa que pueda escribir usted mismo. La única situación que debería considerar hacer suya es si puede articular una necesidad muy específica, de misión crítica, que los algoritmos STL no satisfacen.

Editado para añadir: (Muy bien, así que no es realmente siempre, pero si usted tiene que preguntarse si debe usar STL, la respuesta es "sí".)

+6

+1, incluso si yo diría simplemente: siempre que sea posible –

+3

+1 - no podría haberlo dicho mejor. ¿Por qué codificar un algoritmo que ya existe y que se ha probado exhaustivamente? –

+0

Estoy de acuerdo con su respuesta. Pero, nunca veo a nadie usándolos. Por qué no? – zooropa

-2

¿Se utilizan con mayor frecuencia de lo que parece

Nunca los he visto usar; excepto en libros. Tal vez se utilizan en la implementación de la propia STL. Tal vez se volverán más usados ​​porque son más fáciles de usar (vea por ejemplo Lambda functions and expressions), o incluso se volverán obsoletos (vea por ejemplo el Range-based for-loop), en la próxima versión de C++.

+0

¿Puede alguien explicar el voto a favor? ¿Es porque los algoritmos de STL se usan con frecuencia? Por cierto, el enlace es muy interesante. – zooropa

+2

-1, son utilizados por cualquier persona que sepa cómo usarlos, y el bucle for basado en rango difícilmente es un reemplazo para ellos. – greyfade

+0

@zooropa "¿Es porque los algoritmos STL se usan con frecuencia?" SÍ – Artyom

14

Algoritmos STL deben usarse siempre que se ajusten a lo que necesita hacer. Que es casi todo el tiempo.

6

Hay muchos buenos algoritmos además de cosas como std::foreach.

Sin embargo, hay un montón de algoritmos no triviales y muy útiles:

  • clasificar: std::sort, std::upper_bound, std::lower_bound, std::binary_search
  • Min/Max std::max, std::min, std::partition, std::min_element, std::max_element
  • Buscar como std::find, std::find_first_of etc.

Y muchos otros.

algoritmos como std::transform son mucho más útil con las expresiones lambda C++ 0x o cosas por el estilo boost::lambda o boost::bind

7

escribo aplicaciones críticas de rendimiento. Estos son los tipos de cosas que necesitan procesar millones de piezas de información en el menor tiempo posible. No podría hacer algunas de las cosas que hago ahora si no fuera por STL. Úselos siempre.

+10

Los algoritmos STL [sic] no son nada que no puedas escribir tú mismo, no son mágicos. –

+7

@Niel: No, pero están bien escritos. – greyfade

+0

@Niel: Tienes razón en muchos aspectos. Sin embargo, los autores de la biblioteca de una implementación determinada tienen acceso a la información interna. Esto es especialmente cierto para cosas como 'hash_map' y' hash_multimap' que no son compatibles con los estándares. – wheaties

3

Si tuviera que escribir algo esta tarde, y supiera cómo hacerlo usando bucles hechos a mano y tendría que descubrir cómo hacerlo en algoritmos STL, lo escribiría usando bucles hechos a mano.

Habiendo dicho eso, me gustaría trabajar para hacer que los algoritmos STL sean una parte confiable de mi toolkit, por razones articuladas en las otras respuestas.

-

razones es posible que no se ve es en código es que es o bien el código heredado o escrito por los programadores de legado. Tuvimos aproximadamente 20 años de programación en C++ antes de que saliera el STL, y en ese momento teníamos una comunidad de programadores que sabían cómo hacer las cosas a la vieja usanza y que aún no habían aprendido el camino de STL. Esto probablemente permanecerá por una generación.

+2

"una comunidad de programadores que sabían cómo hacer las cosas a la vieja usanza y que aún no habían aprendido el camino de STL". Considero que std :: string y los contenedores estándar han sido mucho más ampliamente adoptados que los algoritmos. Quiero decir, "' count_if (v.begin, v.end, bind1st (mayor (), 7), littleNums) '": por favor. – ChrisW

+1

FWIW, me duele la cabeza (y desperdicia algo de tiempo) cada vez que tengo que averiguar cómo hacer 'bind1st' y otras cosas para que funcionen correctamente, y el código con el que termino a menudo no es más claro que un simple viejo' para (some_iterator = c.begin(); ...) 'loop. Digo usar los algoritmos cuando hacen algo que no sea trivial, pero no se vuelvan religiosos con respecto a ellos. –

+1

@ChrisW: Espero que esté relacionado con el hecho de que los sustantivos están menos ligados en la mente que los verbos, por lo que los objetos son más fáciles de aprender que las nuevas formas de construir algoritmos. –

12

¿Cuándo deben usarse los algoritmos STL en lugar de utilizar los propios?

Cuando valoras tu tiempo y cordura y tienes cosas más divertidas que hacer que reinventando la rueda una y otra vez.

Necesita usar sus propios algoritmos cuando el proyecto lo requiera, y no hay alternativas aceptables para escribir cosas, o si identificó el algoritmo STL como un cuello de botella (usando el generador de perfiles, por supuesto) o tiene algún tipo de restricciones STL no se ajusta a, o la adaptación de STL para la tarea tomará más tiempo que escribir el algoritmo desde cero (tuve que usar la versión retorcida de la búsqueda binaria algunas veces ...). STL no es perfecto y no es apto para todo, pero cuando puedes, debes usarlo. Cuando alguien ya hizo todo el trabajo por usted, con frecuencia no hay razón para hacer lo mismo otra vez.

+0

+1 para señalar que 'siempre' no siempre funciona. Escribí para dispositivos DSP que no tienen soporte para STL o son malos, en cuyo caso la opción más fácil es escribir la suya propia. – stijn

16

Ya has obtenido varias respuestas, pero no puedo estar de acuerdo con ninguna de ellas. Algunos se acercan bastante a la marca, pero no mencionan el punto crucial (IMO, por supuesto).

Al menos para mí, el punto crucial es bastante simple: debes usar los algoritmos estándar cuando ayudan a a aclarar el código que estás escribiendo.

Es así de simple. En algunos casos, lo que está haciendo requeriría una invocación misteriosa usando std::bind1st y std::mem_fun_ref (o algo de ese orden) que es extremadamente denso y opaco, donde un bucle for sería casi trivialmente simple y directo. En tal caso, siga adelante y use el ciclo for.

Si no hay un algoritmo estándar que haga lo que desea, tenga cuidado y mire de nuevo; a menudo habrá omitido algo que realmente hará lo que desea (un lugar que a menudo se pierde: los algoritmos en <numeric> son a menudo útil para usos no numéricos). Habiendo mirado un par de veces, y confirmado que hay realmente no es un algoritmo estándar para hacer lo que desea, en lugar de escribir ese for bucle (o lo que sea) en línea, considere escribir un algoritmo genérico para hacer lo que necesita hacer. Si lo está usando en un solo lugar, hay muchas posibilidades de que pueda usarlo dos o tres más, y en ese punto puede ser una gran victoria en cuanto a claridad.

Escribir algoritmos genéricos no es tan difícil; de hecho, a menudo es casi ningún trabajo extra en comparación con escribir un ciclo en línea, por lo que incluso si solo puede usarlo dos veces, ya está ahorrando un poco de trabajo , incluso si ignora la mejora en la legibilidad y claridad del código.

+5

Es una buena respuesta, sin embargo, con respecto a 'bind1st', etc. - fueron obsoletos por' bind' cuando TR1 fue ampliamente implementado, y ahora están siendo rápidamente obsoletos por C++ 0x lambdas (tanto MSVC como g ++ ya tienen soporte, aunque con algunas peculiaridades menores).Una vez que las lambdas entran en escena, realmente no existen buenas razones para no usar un algoritmo de stock sobre un bucle codificado a mano, ya que la legibilidad/claridad va a ser universalmente a favor del algoritmo + lambda. –

+1

@Pavel: en gran parte cierto, aunque creo que un punto es importante: los grandes proyectos a menudo siguen utilizando compiladores antiguos mucho después de que estén "obsoletos". –

+0

Además, cuando tiene un cuerpo grande de código que usa un método probado y probado en la empresa, no necesariamente quiere agregar una variante al sistema. Mejor que todo sea consistente. – lilburne

2

La única vez que no uso los algoritmos STL es cuando las diferencias de implementación multiplataforma afectan el resultado de mi programa. Esto solo ha sucedido en uno o dos casos excepcionales (en la Playstation 3). Aunque la interfaz de STL está estandarizada en todas las plataformas, la implementación no lo es.

Además, en ciertas aplicaciones de muy alto rendimiento (como los videojuegos, los servidores de videojuegos), hemos reemplazado algunas estructuras STL con las nuestras para obtener un poco más de eficiencia.

Sin embargo, la gran mayoría de las veces el uso de STL es el camino a seguir. Y en mis otros trabajos (sin videojuegos), utilicé el STL exclusivamente.

1

tener en cuenta que los algoritmos STL cubren una gran cantidad de bases, pero la mayoría de los desarrolladores de C++, probablemente va a terminar la codificación algo que hace algo equivalente a std::find(), std::find_if() y std::max() casi todos los días de su vida laboral (si no están usando las versiones de STL ya). Al utilizar las versiones de STL, separa el algoritmo tanto del flujo lógico de su código como de la representación de datos.

Para otros algoritmos STL menos comúnmente utilizados tales como std::merge() o std::lower_bound() estos son enormemente rutinas útiles (la primera para la fusión de dos contenedores ordenados, el segundo para trabajar a dónde insertar un elemento en un recipiente para mantenerlo ordenó). Si tuviera que intentar implementarlo usted mismo, probablemente le llevaría algunos intentos (los algoritmos no son complicados, pero probablemente obtendrá errores uno a uno o similares).

Yo mismo los utilizo todos los días de mi carrera profesional. Algunas bases de código heredadas que preceden a un STL estable pueden no usarlo extensamente, pero si hay un proyecto más nuevo que lo está evitando intencionalmente, me inclinaría a pensar que fue por un hacker de medio tiempo que estaba todavía trabajando bajo la mitad La suposición de 90 de que las plantillas son lentas y, por lo tanto, deben evitarse.

+0

Uso std :: map not std :: find(). – ChrisW

+0

Eso está bien para una matriz asociativa, pero si solo tienes un vector, lista u otra estructura de datos (el bit claro es que también puedes crear tu propia estructura de datos y siempre que proporciones un 'begin()' y 'end() 'equivalente), luego' std :: find() 'funcionará en todos ellos. El caso de 'std :: map' es una optimización. –

2

El principal problema con los algoritmos STL hasta ahora era que, aunque la llamada al algoritmo en sí misma es más clara, la definición de los funtores que necesitaría pasar a ellos haría su código más largo y más complejo, debido a la forma en que el lenguaje te obligó a hacerlo. Se espera que C++ 0x cambie eso, con su soporte para expresiones lambda.

He estado utilizando STL en gran medida durante los últimos 6 años y aunque traté de usar algoritmos STL en cualquier lugar que pude, en la mayoría de los casos haría que mi código fuera más oscuro, así que volví a un bucle simple. Ahora con C++ 0x es lo opuesto, el código parece siempre parecer más simple con ellos.

El problema es que, por ahora, el soporte de C++ 0x todavía está limitado a unos pocos compiladores, incluso porque el estándar aún no está completamente terminado. Entonces probablemente tendremos que esperar algunos años para ver realmente el uso generalizado de los algoritmos STL en el código de producción.

1

yo no usaría STL en dos casos:

  1. Cuando STL no está diseñado para su tarea. STL es casi lo mejor para propósitos generales. Sin embargo, para aplicaciones específicas, STL puede no ser siempre el mejor. Por ejemplo, en uno de mis programas, necesito una enorme tabla hash mientras que la equivalencia hashmap de STL/tr1 requiere demasiada memoria.

  2. Cuando está aprendiendo algoritmos. Soy uno de los pocos que disfruta reinventando las ruedas y aprendiendo mucho en este proceso. Para ese programa, reimplementé una tabla hash. Realmente me llevó mucho tiempo, pero al final todos los esfuerzos dieron sus frutos.Aprendí muchas cosas que benefician enormemente mi carrera futura como programador.

1

Cuando crea que puede codificar mejor que un codificador muy inteligente que spents semanas investigando y pruebas y tratando de hacer frente a todo conjunto concebible de entradas.

¡Para la mayoría de los terrícolas la respuesta es NUNCA!

Cuestiones relacionadas