Si está trabajando en áreas realmente críticas para el rendimiento, entonces no puede posponer la eficiencia como una ocurrencia tardía. Es una de las cosas más importantes en las que pensar cuando se diseña desde el principio en esos casos y en formas que se relacionan con la mantenibilidad del resultado final.
No puede diseñar e implementar un servidor a gran escala y simplemente comenzar a escribir código fácil y bien documentado que solo utiliza funciones de bloqueo para todo con un bloqueo global de subprocesos que bloquea todo el sistema para procesar cada solicitud individual del cliente sin poner ningún pensado en estado compartido, contención de hilos y asincronía. Tal es una receta para el desastre y la necesidad de rediseñar y reescribir la mayor parte del código bien documentado que escribió de manera que podría conducir a la base de código más difícil de mantener imaginable, plagada de condiciones de carrera y puntos muertos como resultado de intentar para lograr la eficiencia requerida en retrospectiva, en lugar de haber pensado en diseños eficientes, simples y funcionales por adelantado.
Un equipo de desarrollo de juegos a los 8 meses de producción con un motor que solo pasa 2 cuadros por segundo en su hardware más robusto con 32 núcleos, mientras que tiene una tendencia a detenerse durante 15 segundos cada vez que la pantalla se llena, es poco probable que obtenga un producto utilizable de forma instantánea con solo arreglando un pequeño punto de acceso localizado. Lo más probable es que su diseño sea FUBAR de formas que justifiquen una revisión épica del tablero de dibujo y cambios de diseño que podrían caer en cascada en cada esquina de la base de código.
Con John Carmack, habló una vez sobre cómo una demostración tecnológica debe ejecutarse a un mínimo de cientos a miles de cuadros por segundo para integrarla en la producción. Esa no es una obsesión poco saludable con la eficiencia. Él sabe por adelantado que los juegos deben ejecutarse, en su totalidad, a más de 30 FPS para que los clientes lo encuentren aceptable. Como resultado, un pequeño aspecto como un sistema de sombra suave no puede ejecutarse a 30 FPS, o el juego en su conjunto no puede ser lo suficientemente rápido como para proporcionar la retroalimentación requerida en tiempo real. Es inutilizable hasta que logre la eficiencia requerida. En esas áreas críticas de rendimiento donde hay un requisito fundamental para la eficiencia, una solución que no logra alcanzar la velocidad adecuada en realidad no es mejor que una que no funciona en absoluto,. Y no puede diseñar un sistema eficiente de sombras suaves que se ejecute a cientos o miles de cuadros por segundo como se requiere para un motor de juego en tiempo real, a menos que ponga una cantidad predominante de pensamiento por adelantado en cuanto a su eficiencia. De hecho, en tales casos, más del 90% del trabajo está orientado a la eficiencia, ya que es trivial crear un sistema de sombra suave que funcione bien a las 2 horas por cuadro utilizando el trazado de ruta, pero no puede esperar ajustarlo. para correr a cientos de cuadros por segundo sin un cambio de enfoque totalmente diferente.
Cuando la eficiencia es una parte fundamental del diseño de una aplicación, no puede esperar lograr eficiencia en retrospectiva sin perder dramáticamente más tiempo del que ahorró al ignorarla, ya que no puede esperar lograr un diseño funcional en retrospectiva. Nadie dice: " está bien posponer pensar en el diseño hasta más tarde. Simplemente documente bien su código y podrá encontrar un diseño adecuado más adelante ". Pero en arquitecturas de rendimiento crítico, eso es lo que está haciendo efectivamente si no pone mucha atención y pensamiento en diseños eficientes por adelantado.
Ahora, eso no significa que deba microajustar sus implementaciones de inmediato. Para detalles de implementación, hay mucho espacio para iterar hacia soluciones más rápidas después de medir, siempre que el diseño no tenga que cambiar y, a menudo, esa es la forma más productiva de hacerlo. Pero a nivel de diseño, significa que debe pensar lo suficiente en cómo el diseño y la arquitectura se relacionarán con la eficiencia desde el principio.
La diferencia clave aquí es diseño.. No es fácil hacer grandes cambios en los diseños en retrospectiva, ya que los diseños acumulan dependencias, y las dependencias se romperán si el diseño cambia. Y si un diseño tiene el requisito de ser razonablemente eficiente o, en algunos casos, que su calidad se mide en gran medida por su eficiencia, entonces no debe esperar poder lograr un diseño adecuado como una ocurrencia tardía. Con cualquier producto competitivo donde la eficiencia es un gran aspecto de la calidad, ya sean sistemas operativos o compiladores o procesadores de video o raytracers o motores de juegos o motores de física, las reflexiones sobre la eficiencia y las representaciones de datos se pensaron meticulosamente desde el principio. Y en esos casos, no es una optimización prematura pensar tanto en la eficiencia por adelantado. Estaba colocando tal pensamiento exactamente en el momento más productivo para hacerlo,