¿Cuándo la optimización no es prematura y, por lo tanto, no es mala?

75

"La optimización prematura es la raíz de todo mal" es algo que casi todos hemos escuchado / leído. Tengo curiosidad por saber qué tipo de optimización no es prematura, es decir, en cada etapa del desarrollo de software (diseño de alto nivel, diseño detallado, implementación de alto nivel, implementación detallada, etc.) qué es el grado de optimización que podemos considerar sin pasar al lado oscuro.

    
pregunta Gaurav 01.01.2011 - 08:10

13 respuestas

112

¿Cuándo lo estás basando en la experiencia? No malvado "Cada vez que hemos hecho X, hemos sufrido un golpe de rendimiento brutal. Planifiquemos o optimizando o evitando X por completo esta vez".

¿Cuándo es relativamente indoloro? No malvado "Implementar esto como Foo o Bar llevará mucho trabajo, pero en teoría, Bar debería ser mucho más eficiente. Vamos a prohibirlo".

¿Cuando estás evitando los algoritmos de mierda que se escalarán terriblemente? No malvado "Nuestro jefe de tecnología dice que nuestro algoritmo de selección de ruta propuesto se ejecuta en tiempo factorial; no estoy seguro de lo que eso significa, pero ella sugiere que cometamos seppuku incluso por considerarlo. Consideremos otra cosa".

El mal viene de gastar una gran cantidad de tiempo y energía para resolver problemas que no sabes que realmente existen. Cuando los problemas definitivamente existen, o cuando los psico-problemas fantasmas pueden resolverse a bajo costo, el mal desaparece.

Steve314 y Matthieu M. resalta puntos en los comentarios que deberían ser considerados. Básicamente, algunas variedades de optimizaciones "indoloras" simplemente no valen la pena, ya que la mejora de rendimiento trivial que ofrecen no vale la pena de ofuscación de código, son mejoras de duplicación que el compilador ya está realizando, o ambas cosas. Vea los comentarios para ver algunos ejemplos agradables de no mejoras demasiado inteligentes por la mitad.

    
respondido por el BlairHippo 01.01.2011 - 08:45
35

El código de la aplicación solo debe ser tan bueno como sea necesario, pero código de biblioteca debería ser lo mejor posible, ya que nunca se sabe cómo se va a utilizar su biblioteca. Por lo tanto, cuando escribe un código de biblioteca, debe ser bueno en todos los aspectos, ya sea en rendimiento, solidez o en cualquier otra categoría.

Además, debe pensar en el rendimiento cuando diseñe su aplicación y cuando seleccione algoritmos . Si no está diseñado para ser eficaz, ningún grado de piratería puede hacerlo después y ninguna microoptimización superará a un algoritmo superior.

    
respondido por el sbi 01.01.2011 - 21:39
24
  

qué tipo de optimización [no es] prematura

El tipo que viene como resultado de problemas conocidos.

    
respondido por el George Marian 01.01.2011 - 08:34
17
  

¿Cuándo la optimización no es prematura y, por lo tanto, no es mala?

Es difícil decir qué es el bien y el mal. ¿Quién tiene ese derecho? Si observamos la naturaleza, parece que estamos programados para sobrevivir con una definición amplia de "supervivencia" que incluye transmitir nuestros genes a la descendencia.

Así que diría, al menos de acuerdo con nuestras funciones y programación básicas, que la optimización no es mala cuando se alinea con el objetivo de la reproducción. Para los chicos, están las rubias, morenas, pelirrojas, muchas encantadoras. Para las chicas, hay chicos, y algunos de ellos parecen estar bien.

Quizás deberíamos estar optimizando para ese propósito, y ahí ayuda usar un perfilador. El generador de perfiles le permitirá priorizar sus optimizaciones y el tiempo de manera más efectiva además de brindarle información detallada sobre los puntos de acceso y por qué ocurren. Esto le dará más tiempo libre dedicado a la reproducción y su búsqueda.

    
respondido por el user204677 03.01.2016 - 20:19
15

La cita completa define cuando la optimización es no prematuro:

  

Un buen programador no se dejará llevar por la complacencia con tal razonamiento, será prudente que mire cuidadosamente el código crítico; pero solo después de que ese código haya sido identificado . [énfasis mío]

Puede identificar el código crítico de muchas maneras: las estructuras de datos críticos o los algoritmos (p. ej., utilizados en gran medida o el "núcleo" del proyecto) pueden proporcionar optimizaciones mayores, muchas optimizaciones menores se identifican a través de los perfiladores, y así sucesivamente.

    
respondido por el Fred Nurk 14.01.2011 - 00:56
11

Siempre debe elegir una solución "suficientemente buena" en todos los casos en función de sus experiencias.

El dicho de optimización se refiere a escribir "código más complejo que 'lo suficientemente bueno' para hacerlo más rápido" antes de saber realmente que es necesario, por lo que el código es más complejo de lo necesario. La complejidad es lo que dificulta las cosas, por lo que no es algo bueno.

Esto significa que no debe elegir un super complejo "puede ordenar los archivos de 100 Gb cambiando de forma transparente a la rutina de clasificación de disco" cuando se realice una clasificación simple, pero también debe hacer una buena elección para la clasificación simple en primer lugar . Elegir ciegamente Bubble Sort o "elegir todas las entradas al azar y ver si están en orden. Repetir". rara vez es bueno.

    
respondido por el user1249 01.01.2011 - 09:33
3

Mi regla general: si no está seguro de que necesitará la optimización, suponga que no. Pero tenlo en cuenta para cuando necesites optimizar. Sin embargo, hay algunos problemas que puede conocer por adelantado. Esto generalmente implica elegir buenos algoritmos y estructuras de datos. Por ejemplo, si necesita verificar la membresía en una colección, puede estar bastante seguro de que necesitará algún tipo de estructura de datos establecida.

    
respondido por el Jason Baker 01.01.2011 - 21:52
3

En mi experiencia, en la fase de implementación detallada, la respuesta está en perfilar el código. Es importante saber qué necesita ser más rápido y qué es aceptablemente rápido.

También es importante saber dónde está exactamente el cuello de botella del rendimiento: la optimización de una parte del código que toma solo el 5% del tiempo total para ejecutar no sirve de nada.

Los pasos 2 y 3 describen una optimización no prematura:

  1. Haz que funcione
  2. prueba. ¿No suficientemente rápido? Perfílelo .
  3. Utilizando los datos del paso 2, optimice las secciones más lentas del código.
respondido por el Gorgi Kosev 07.01.2011 - 00:28
3

No es una optimización al elegir cosas que son difíciles de cambiar, por ejemplo: plataforma de hardware.

Seleccionar estructuras de datos es un buen ejemplo: crítico para cumplir con los requisitos funcionales y no funcionales (rendimiento). No se cambia fácilmente y, sin embargo, impulsará todo lo demás en tu aplicación. Sus estructuras de datos cambian los algoritmos disponibles, etc.

    
respondido por el jasonk 15.03.2012 - 14:24
3

Sólo conozco una forma de responder a esta pregunta, y es obtener experiencia en el ajuste del rendimiento. Eso significa: escribe programas, y después se escriben, encuentra aceleraciones en ellos y hazlo de manera iterativa. Aquí hay un ejemplo.

Este es el error que cometen la mayoría de las personas: intentan optimizar el programa antes que realmente lo ejecuta. Si han tomado un curso de programación (de un profesor que en realidad no tiene mucha experiencia práctica) tendrán gafas de color de gran O, y pensarán que de eso se trata todo . Es todo el mismo problema, optimización previa. **

Alguien dijo: Primero hazlo bien, luego hazlo rápido. Tenían razón.

Pero ahora para el pateador: si has hecho esto varias veces, reconoces las cosas tontas que hiciste anteriormente que causan problemas de velocidad, por lo que las evitas por instinto. (Cosas como hacer que la estructura de su clase sea demasiado pesada, abrumarse con notificaciones, confundir el tamaño de las llamadas de función con su costo de tiempo, la lista sigue y sigue ...) Usted evita estos instintivamente, pero adivine qué aspecto tiene el menos experimentado: ¡ optimización prematura!

Así que estos debates tontos siguen y siguen :)

** Otra cosa que dicen es que ya no tienes que preocuparte más, porque los compiladores son muy buenos y las máquinas son muy rápidas en la actualidad. (KIWI - Mátalo con hierro.) No hay aceleraciones de hardware o de sistema exponenciales (hechas por ingenieros muy inteligentes que trabajan duro) que posiblemente puedan compensar las desaceleraciones de software exponenciales (hechas por programadores que piensan de esta manera).

    
respondido por el Mike Dunlavey 30.09.2015 - 15:46
2

Cuando los requerimientos o el mercado lo soliciten específicamente.

Por ejemplo, el rendimiento es un requisito en la mayoría de las aplicaciones financieras porque la baja latencia es crucial. Dependiendo de la naturaleza del instrumento comercializado, la optimización puede ir desde el uso de algoritmos sin bloqueo en un lenguaje de alto nivel hasta el uso de un lenguaje de bajo nivel e incluso lo más extremo: implementar los algoritmos de coincidencia de órdenes en el propio hardware (utilizando FPGA, por ejemplo). ).

Otro ejemplo sería algunos tipos de dispositivos integrados. Tomemos, por ejemplo, el freno ABS; En primer lugar está la seguridad, cuando golpeas la rotura, el coche debería disminuir la velocidad. Pero también hay rendimiento, no querrás ningún retraso cuando llegues a la pausa.

    
respondido por el m3th0dman 16.06.2015 - 09:24
0

La mayoría de las personas diría que la optimización es prematura, si está optimizando algo que no produce un "fallo suave" (funciona pero sigue siendo inútil) del sistema debido al rendimiento.

Ejemplos del mundo real.

  • Si mi ordenación de burbujas tarda 20ms en ejecutarse, optimizándola a 1ms quicksort no va a mejorar la utilidad general de ninguna manera significativa a pesar de ser un aumento del rendimiento del 2000%.

  • Si una página web tarda 20s en cargarse y la reducimos a 1s, este Puede aumentar la utilidad del sitio web desde 0 hasta casi el infinito. Básicamente, algo que se rompió porque era demasiado lento, ahora es útil.

respondido por el Eric 15.06.2015 - 21:59
0

¿Qué tipo de optimización no es prematura?

Una optimización que soluciona un problema de rendimiento conocido con su aplicación, o una optimización que le permite a su aplicación cumplir con criterios de aceptación bien definidos.

Una vez identificado, se debe tomar algún tiempo para establecer la solución y se debe medir el beneficio de rendimiento.

(es decir, no lo es - "Creo que este bit del código parece que podría ser lento, cambiaré X para usar Y y eso será más rápido").

Me he encontrado con muchas "optimizaciones" prematuras que, en última instancia, han hecho que el código sea más lento. En este caso, estoy tomando la prematura como "no pensado". El rendimiento debe evaluarse antes y después de la optimización, y solo el código que realmente mejora el rendimiento se mantiene.

    
respondido por el Paddy 20.12.2017 - 17:44

Lea otras preguntas en las etiquetas