Normalmente odio la palabra "optimización prematura", pero esto apesta. Vale la pena señalar que Knuth usó esta famosa cita en el contexto de presionar para usar goto
declaraciones para acelerar el código en áreas críticas . Esa es la clave: caminos críticos .
Estaba sugiriendo usar goto
para acelerar el código, pero advirtió contra aquellos programadores que desearían hacer este tipo de cosas basadas en corazonadas y supersticiones de código que ni siquiera es crítico.
Favorecer las switch
declaraciones lo más uniformemente posible a lo largo de una base de código (ya sea que se maneje o no una carga pesada) es el ejemplo clásico de lo que Knuth llama el programador "centavo y tonto" que pasa todo el día luchando por mantener su "optimizado" "código que se convirtió en una pesadilla de depuración como resultado de intentar ahorrar centavos por libras. Dicho código rara vez se puede mantener y mucho menos incluso eficiente en primer lugar.
¿Tiene razón?
Es correcto desde la perspectiva de eficiencia muy básica. Que yo sepa, ningún compilador puede optimizar el código polimórfico que involucra objetos y el despacho dinámico mejor que una declaración de cambio. Nunca terminará con una LUT o una tabla de salto al código en línea del código polimórfico, ya que dicho código tiende a servir como una barrera optimizadora para el compilador (no sabrá a qué función llamar hasta el momento en que el envío dinámico ocurre).
Es más útil no pensar en este costo en términos de tablas de salto, sino más en términos de la barrera de optimización. Para el polimorfismo, la llamada Base.method()
no permite que el compilador sepa qué función realmente se llamará si method
es virtual, no está sellada y puede anularse. Dado que no sabe qué función se va a llamar de antemano, no puede optimizar la llamada a la función y utilizar más información para tomar decisiones de optimización, ya que no sabe qué función se va a llamar en la hora en que se compila el código.
Los optimizadores están en su mejor momento cuando pueden mirar en una llamada de función y hacer optimizaciones que aplanan por completo a la persona que llama y a la persona que llama, o al menos optimizan a la persona que llama para trabajar de manera más eficiente con la persona que llama. No pueden hacer eso si no saben qué función se llamará de antemano.
¿Solo está hablando por el culo?
Usar este costo, que a menudo equivale a centavos, para justificar convertirlo en un estándar de codificación aplicado de manera uniforme es generalmente muy tonto, especialmente para lugares que tienen una necesidad de extensibilidad. Eso es lo principal que debe tener en cuenta con los optimizadores prematuros genuinos: quieren convertir las preocupaciones menores de rendimiento en estándares de codificación aplicados de manera uniforme en una base de código sin tener en cuenta el mantenimiento en absoluto.
Sin embargo, me ofende un poco la cita del "viejo pirata informático C" utilizada en la respuesta aceptada, ya que soy uno de esos. No todos los que han estado codificando durante décadas a partir de un hardware muy limitado se han convertido en un optimizador prematuro. Sin embargo, también me he encontrado y trabajado con ellos. Pero esos tipos nunca miden cosas como predicciones erróneas de sucursales o errores de caché, piensan que saben mejor y basan sus nociones de ineficiencia en una base de código de producción compleja basada en supersticiones que hoy en día no son ciertas y a veces nunca lo fueron. Las personas que han trabajado genuinamente en campos críticos para el rendimiento a menudo entienden que la optimización efectiva es una priorización efectiva, y tratar de generalizar un estándar de codificación que degrada el mantenimiento para ahorrar centavos es una priorización muy ineficaz.
Los centavos son importantes cuando tienes una función barata que no hace tanto trabajo, que se llama mil millones de veces en un ciclo muy apretado y crítico para el rendimiento. En ese caso, terminamos ahorrando 10 millones de dólares. No vale la pena afeitarse centavos cuando tiene una función llamada dos veces para la cual el cuerpo solo cuesta miles de dólares. No es aconsejable pasar el tiempo regateando centavos durante la compra de un automóvil. Vale la pena regatear centavos si está comprando un millón de latas de refresco a un fabricante. La clave para una optimización efectiva es comprender estos costos en su contexto adecuado. Alguien que intenta ahorrar centavos en cada compra y sugiere que todos los demás intenten regatear centavos sin importar lo que compren, no es un optimizador experto.