El aspecto clave de la cita de Knuth para mí es "penique sabio y libra tonta". Así es como finalmente describió al optimizador prematuro: alguien que regatea por ahorrar centavos cuando hay libras para ahorrar, y que lucha por mantener su software "optimizado" (preste especial atención a cómo utilizó las comillas aquí).
Encuentro que muchas personas a menudo solo citan una pequeña parte del artículo de Knuth. Vale la pena darse cuenta de que su periódico argumentaba que debía usar goto
para acelerar las rutas de ejecución críticas en el software.
Una cita más completa:
[...] esto es un ahorro notable en la velocidad de funcionamiento global, si, por ejemplo, el valor medio de n es aproximadamente 20, y si se lleva a cabo la rutina de búsqueda aproximadamente un millón de veces en el programa. Tales optimizaciones de bucle [usando gotos] no son difíciles de aprender y, como ya he dicho, son apropiadas solo en una pequeña parte de un programa, pero a menudo producen ahorros sustanciales. [...]
La sabiduría convencional compartida por muchos de los ingenieros de software de hoy llama a ignorar la eficiencia en el pequeño; pero creo que esto es simplemente una reacción exagerada a los abusos que ven que se practican por programadores de centavo y libra-tonto, que no pueden depurar o mantienen sus programas "optimizados". En las disciplinas de ingeniería establecidas , una mejora del 12%, de fácil obtención, nunca se considera marginal; y creo que el mismo punto de vista debería prevalecer en la ingeniería del software . Por supuesto, no me molestaría en hacer tales optimizaciones en un trabajo único, pero cuando se trata de preparar programas de calidad, no quiero restringirme a herramientas que me nieguen dichas eficiencias .
No hay duda de que el grial de la eficiencia conduce al abuso. Los programadores pierden enormes cantidades de tiempo pensando o preocupando sobre la velocidad de las partes no críticas de sus programas, y estos intentos de eficacia tienen un fuerte impacto negativo cuando se consideran la eliminación y el mantenimiento de . Deberíamos olvidar las pequeñas eficiencias , digamos el 97% del tiempo; La optimización prematura es la raíz de todos los males.
A menudo es un error hacer juicios a priori sobre qué partes de un programa son realmente crítico, ya que la experiencia universal de programadores que han estado utilizando herramientas de medición ha sido que sus conjeturas intuitivas fallan. Después de trabajar con estas herramientas durante siete años, me he convencido de que todos los compiladores escritos de ahora en adelante deberían diseñarse para proporcionar a todos los programadores comentarios que indiquen qué partes de sus programas cuestan más; de hecho, esta retroalimentación debe ser proporcionada automáticamente a menos que haya sido específicamente desactivada.
Después de un programador sabe qué partes de sus rutinas son realmente importantes, una transformación como duplicar bucles valdrá la pena. Tenga en cuenta que esta transformación introduce sentencias go to
, y también lo hacen otras optimizaciones de bucle.
Así que esto viene de alguien que en realidad era profundamente preocupados con el rendimiento en el nivel micro, y en el momento (optimizadores han conseguido mucho mejor ahora), se utiliza para goto
velocidad.
En el corazón de la creación de la "optimizador prematura" de este Knuth es:
- Optimizar basan en corazonadas/supersticiones/intuiciones humanas sin experiencia o mediciones (de optimización a ciegas, sin saber realmente lo que está haciendo el pasado)
- Optimización de una manera que ahorra centavos en libras (optimizaciones ineficaces).
- Buscando el máximo absoluto absoluto de eficiencia para todo.
- Buscando eficiencia en rutas no críticas.
- Tratando de optimizar cuando apenas puede mantener/depurar su código.
Nada de esto tiene que ver con el momento de sus optimizaciones, sino con la experiencia y la comprensión, desde la comprensión de las rutas críticas hasta la comprensión de lo que realmente ofrece el rendimiento.
Las cuestiones como el desarrollo basado en pruebas y un enfoque predominante en el diseño de la interfaz no se cubrieron en el documento de Knuth. Estos son conceptos e ideas más modernos. Estaba concentrado en la implementación principalmente.
Sin embargo, es una buena actualización de los consejos de Knuth: intentar establecer la exactitud primero a través de pruebas y diseños de interfaz que le permitan optimizar sin romper todo.
Si tratamos de aplicar una interpretación moderna de Knuth, agregaría "enviar" allí. Incluso si está optimizando las verdaderas rutas críticas de su software con ganancias medidas, el software más rápido del mundo no tiene valor si nunca se envía. Tener eso en cuenta debería ayudarte a hacer compromisos más inteligentes.
Me estoy inclinando por simplemente ir a la base de datos varias veces, lo que I creo que es la mudanza correcta aquí. Es más importante que termine el proyecto y siento que me estoy colgando por las optimizaciones de esta manera. Mi pregunta es: ¿esta es la estrategia correcta para usar cuando evitando la optimización prematura?
Depende de usted el mejor juicio, teniendo en cuenta algunos de los puntos anteriores, ya que comprende más íntimamente sus propios requisitos.
Un factor crucial que sugeriría es que, si se trata de una ruta de rendimiento crítico para una carga pesada, diseñe sus interfaces públicas de manera que deje mucho espacio para optimizar.
Por ejemplo, no diseñe un sistema de partículas con dependencias de cliente en una interfaz Particle
. Eso no deja espacio para optimizar, cuando solo tiene que trabajar con el estado encapsulado y la implementación de una sola partícula. En ese caso, es posible que deba realizar cambios en cascada en su base de código para optimizar. Un auto de carreras no puede utilizar su velocidad si el camino tiene solo 10 metros de largo. En su lugar, diseñe hacia la interfaz ParticleSystem
que agrega un millón de partículas, por ejemplo, con operaciones de mayor nivel que se ocupan de partículas a granel cuando sea posible. Eso le deja mucho espacio para optimizar sin romper sus diseños si encuentra que necesita optimizar.
El lado perfeccionista de mí quiere que todo sea óptimo y perfecto la primera vez a través, pero me estoy encontrando esto está complicando el diseño un poco.
Ahora esta parte suena un poco prematura. En general, su primer paso debe ser hacia la simplicidad. La simplicidad a menudo va de la mano con razonablemente rápido, más rápido de lo que piensas incluso si estás haciendo un trabajo redundante.
De todos modos, espero que estos puntos ayuden al menos a agregar algunas cosas más a consideración.
Ha habido mucha discusión sobre esto antes: http://stackoverflow.com/search?q=premature+optimization –
Si nos dices qué idioma y base de datos estás utilizando, las personas podrían ser ilustrativas ejemplos. Me doy cuenta de que su pregunta es general, pero los ejemplos a menudo ayudan. – detly
@detly: es una aplicación web respaldada por php/mysql. –