performance - ¿Debe un desarrollador apuntar primero a la legibilidad o el rendimiento?
readability (30)
A menudo, un desarrollador se enfrentará a una elección entre dos formas posibles de resolver un problema: una que es idiomática y legible, y otra que es menos intuitiva, pero puede tener un mejor rendimiento. Por ejemplo, en los lenguajes basados en C, hay dos formas de multiplicar un número por 2:
int SimpleMultiplyBy2(int x)
{
return x * 2;
}
y
int FastMultiplyBy2(int x)
{
return x << 1;
}
La primera versión es más fácil de seleccionar para lectores técnicos y no técnicos, pero la segunda puede tener un mejor rendimiento, ya que el cambio de bit es una operación más simple que la multiplicación. (Por ahora, supongamos que el optimizador del compilador no detectaría esto y lo optimizaría, aunque eso también es una consideración).
Como desarrollador, ¿cuál sería mejor como primer intento?
¿Cuánto cuesta una hora de tiempo de procesador?
¿Cuánto cuesta una hora de tiempo de programador?
Ambos. Tu código debe equilibrar ambos; legibilidad y rendimiento Porque ignorar cualquiera de ellos arruinará el ROI del proyecto, que al final del día es lo único que le importa a su jefe.
La mala legibilidad da como resultado una menor capacidad de mantenimiento, lo que se traduce en más recursos gastados en mantenimiento, lo que se traduce en un ROI más bajo.
El mal rendimiento resulta en una disminución de la inversión y la base de clientes, lo que resulta en un ROI más bajo.
Como casi todos dijeron en sus respuestas, estoy a favor de la legibilidad . 99 de cada 100 proyectos que ejecuto no tienen requisitos de tiempo de respuesta difíciles, por lo que es una opción fácil.
Antes de comenzar a codificar, ya debes saber la respuesta. Algunos proyectos tienen ciertos requisitos de rendimiento, como ''necesidad de poder ejecutar la tarea X en Y (milli) segundos''. Si ese es el caso, tienes un objetivo al que trabajar y sabes cuándo tienes que optimizarlo o no. (con suerte) esto se determina en la etapa de requisitos de su proyecto, no cuando se escribe el código.
La buena legibilidad y la capacidad de optimizar más adelante son el resultado de un diseño de software adecuado. Si su software es de diseño de sonido, debería poder aislar partes de su software y reescribirlas si es necesario, sin romper otras partes del sistema. Además, la mayoría de los verdaderos casos de optimización que he encontrado (ignorando algunos trucos reales de bajo nivel, que son incidentales) han sido cambiar de un algoritmo a otro, o almacenar datos en caché en la memoria en lugar de disco / red.
Cuanto mayor sea la base de código, más legibilidad es crucial. Tratar de entender alguna función pequeña no es tan malo. (Especialmente porque el Nombre del Método en el ejemplo te da una pista.) No es tan genial para una pieza épica de código súper escrita por el genio solitario que acaba de dejar de codificar porque finalmente ha visto la parte superior de la complejidad de su habilidad y es lo que acaba escribió para ti y nunca lo entenderás.
Depende de la tarea que se deba resolver. Por lo general, la legibilidad es más importante, pero todavía hay algunas tareas en las que debes pensar en el rendimiento en primer lugar. Y no puede simplemente dedicar un día a la creación de perfiles y la optimización una vez que todo funciona a la perfección, ya que la optimización en sí misma puede requerir la reescritura de parte de un código desde cero. Pero no es común hoy en día.
El cambio de bits frente a la multiplicación es una optimización trivial que gana casi nada . Y, como se ha señalado, su compilador debería hacer eso por usted. Aparte de eso, la ganancia es despreciable de todos modos al igual que la CPU en la que se ejecuta esta instrucción.
Por otro lado, si necesita realizar cálculos serios, necesitará las estructuras de datos correctas. Pero si su problema es complejo, descubrirlo es parte de la solución. Como ilustración, considere buscar un número de identificación en una matriz de 1000000 objetos sin clasificar. Luego reconsidere el uso de un árbol binario o un mapa hash.
Pero las optimizaciones como n << C suelen ser negligentes y triviales para cambiar en cualquier punto. Hacer código legible no lo es.
En mi humilde opinión, ambas cosas no tienen nada que ver. Primero debe buscar un código que funcione, ya que esto es más importante que el rendimiento o lo bien que se lee. Respecto a la legibilidad: su código siempre debe ser legible en cualquier caso.
Sin embargo, no veo por qué el código no se puede leer y ofrece un buen rendimiento al mismo tiempo. En su ejemplo, la segunda versión es tan legible como la primera para mí. ¿Qué es menos legible al respecto? Si un programador no sabe que desplazarse a la izquierda es lo mismo que multiplicar por una potencia de dos y desplazar a la derecha es lo mismo que dividir por una potencia de dos ... bueno, entonces usted tiene problemas mucho más básicos que la legibilidad general.
En su ejemplo dado, 99.9999% de los compiladores generarán el mismo código para ambos casos. Lo que ilustra mi regla general: escriba primero para leer y mantener, y optimice solo cuando lo necesite.
La legibilidad es el PRIMER objetivo.
En la década de 1970, el ejército probó algunas de las técnicas "nuevas" de desarrollo de software (diseño de arriba hacia abajo, programación estructurada, equipos de programadores principales, por nombrar algunas) para determinar cuál de estas diferencias estadísticamente significativas.
La ÚNICA técnica que hizo una diferencia estadísticamente significativa en el desarrollo fue ...
AGREGAR LÍNEAS EN BLANCO al código del programa.
La mejora en la legibilidad en esos códigos preestructurados y orientados a objetos fue la única técnica en estos estudios que mejoró la productividad.
==============
La optimización solo debe abordarse cuando todo el proyecto está probado en unidades y listo para la instrumentación. Nunca se sabe DÓNDE se necesita optimizar el código.
En sus libros de referencia, Kernigan y Plauger a fines de la década de 1970 SOFTWARE TOOLS (1976) y SOFTWARE TOOLS IN PASCAL (1981) mostraron formas de crear programas estructurados utilizando el diseño de arriba hacia abajo. Crearon programas de procesamiento de texto: editores, herramientas de búsqueda, preprocesadores de código.
Cuando se completó la función de formateo de texto completo, descubrieron que la mayor parte del tiempo de procesamiento se empleaba en tres rutinas que realizaban entrada y salida de texto (en el libro original, las funciones io tomaban el 89% del tiempo. En el libro pascual, estas funciones ¡consumió el 55%!)
Pudieron optimizar estas TRES rutinas y produjeron los resultados de un mayor rendimiento con un tiempo y un costo de desarrollo razonables y manejables.
La respuesta depende del contexto. En la programación del controlador del dispositivo o el desarrollo del juego, por ejemplo, la segunda forma es una expresión aceptable. En aplicaciones comerciales, no tanto.
Su mejor opción es mirar alrededor del código (o en aplicaciones exitosas similares) para comprobar cómo lo hacen otros desarrolladores.
Legibilidad 100%
Si su compilador no puede hacer la optimización "x * 2" => "x << 1" por usted, ¡obtenga un nuevo compilador!
Recuerde también que el 99,9% del tiempo de su programa se gasta en esperar la entrada del usuario, esperar las consultas de la base de datos y esperar las respuestas de la red. A menos que estés haciendo los múltiples 20 billones de veces, no será notable.
Legibilidad primero Pero incluso más que la legibilidad es la simplicidad, especialmente en términos de estructura de datos.
Me recuerda a un estudiante que hace un programa de análisis de visión, que no podía entender por qué era tan lento. Simplemente siguió una buena práctica de programación: cada píxel era un objeto, y funcionó al enviar mensajes a sus vecinos ...
mira esto
Legibilidad segura No te preocupes por la velocidad a menos que alguien se queje
Legibilidad. El momento de optimizar es cuando llega a la prueba beta. De lo contrario, nunca se sabe realmente lo que necesita para pasar el tiempo.
Legibilidad.
Codificar para el rendimiento tiene su propio conjunto de desafíos. Joseph M. Newcomer lo dijo well
La optimización importa solo cuando importa. Cuando importa, importa mucho, pero hasta que sepa que es importante, no pierda mucho tiempo haciéndolo. Incluso si sabes que importa, necesitas saber dónde importa. Sin datos de rendimiento, no sabrá qué optimizar y probablemente optimizará lo incorrecto.
El resultado será oscuro, difícil de escribir, difícil de depurar y un código difícil de mantener que no resuelve su problema. Por lo tanto, tiene la doble desventaja de (a) aumentar el desarrollo de software y los costos de mantenimiento del software, y (b) no tener ningún efecto de rendimiento en absoluto.
Me gustaría ir por la legibilidad primero. Teniendo en cuenta el hecho de que con el tipo de idiomas optimizados y máquinas de gran carga que tenemos en estos días, la mayoría del código que escribimos en forma legible funcionará decentemente.
En algunos escenarios muy raros, donde estás bastante seguro de que vas a tener un cuello de botella de rendimiento (puede ser debido a malas experiencias pasadas), y lograste encontrar un truco extraño que puede darte una gran ventaja de rendimiento, puedes optar por ese. Pero debería comentar ese fragmento de código muy bien, lo que ayudará a hacerlo más legible.
No tiene sentido optimizar si no conoce sus cuellos de botella. Puede haber hecho que una función sea increíblemente eficiente (generalmente a expensas de la legibilidad hasta cierto punto) solo para descubrir que esa parte del código casi nunca se ejecuta, o le está costando más tiempo acceder al disco o a la base de datos de lo que alguna vez ahorrará trocitos. Por lo tanto, no puedes optimizar tu micro hasta que tengas algo que medir, y luego podrías comenzar a leerlo. Sin embargo, debe tener en cuenta la velocidad y la comprensibilidad al diseñar la arquitectura general, ya que ambos pueden tener un impacto masivo y ser difíciles de cambiar (según el estilo de codificación y las metodologías).
No trabajo en google, así que iría por la opción malvada. (mejoramiento)
En el Capítulo 6 de "Programming Pearls" de Jon Bentley, describe cómo un sistema tenía una velocidad 400 veces superior optimizando en 6 niveles de diseño diferentes. Creo que, al no preocuparse por el rendimiento en estos 6 niveles de diseño, los implementadores modernos pueden lograr fácilmente de 2 a 3 órdenes de magnitud de desaceleración en sus programas.
Poner un comentario allí con una explicación lo haría legible y rápido.
Realmente depende del tipo de proyecto y de la importancia del rendimiento. Si estás construyendo un juego en 3D, generalmente hay muchas optimizaciones comunes que querrás incluir en el camino, y no hay razón para no hacerlo (simplemente no te dejes llevar demasiado pronto). Pero si estás haciendo algo complicado, coméntalo para que cualquiera que lo mire sepa cómo y por qué estás siendo tramposo.
Primero escriba para ser leído, pero espere que los lectores sean programadores . Cualquier programador digno de su sal debería saber la diferencia entre un multiplicador y un cambio de bits, o ser capaz de leer el operador ternario donde se usa apropiadamente, ser capaz de buscar y entender un algoritmo complejo (usted está comentando su código ¿no? ), etc.
La optimización excesiva anticipada es, por supuesto, bastante mala para hacerte tener problemas más adelante cuando necesitas refactorizar, pero eso realmente no se aplica a la optimización de métodos individuales, bloques de código o declaraciones.
Primero, IMO es la versión legible obvia, hasta que se mida el rendimiento y se requiera una versión más rápida.
Se estima que aproximadamente el 70% del costo del software está en mantenimiento. La legibilidad hace que un sistema sea más fácil de mantener y, por lo tanto, reduce el costo del software a lo largo de su vida útil.
Hay casos en los que el rendimiento es más importante que la legibilidad, que dicen que son pocos y distantes.
Antes de sacrificar la legibilidad, piense: "¿Estoy (o su empresa) preparado para enfrentar el costo adicional que estoy agregando al sistema al hacer esto?"
Si le preocupa la legibilidad de su código, no dude en agregar un comentario para recordarse a sí mismo qué y por qué lo hace.
Si no hay legibilidad, será muy difícil mejorar el rendimiento cuando realmente lo necesite.
El rendimiento solo debe mejorarse cuando se trata de un problema en su programa, hay muchos lugares que podrían ser un cuello de botella en lugar de esta sintaxis. Digamos que estás aplastando la mejora de 1n en un << pero ignoraste ese tiempo de IO de 10 minutos.
Además, con respecto a la legibilidad, un programador profesional debe ser capaz de leer / entender los términos de la informática. Por ejemplo, podemos nombrar un método en cola en lugar de decir putThisJobInWorkQueue.
Tómelo de Don Knuth
La optimización prematura es la raíz de todo mal (o al menos la mayor parte) en la programación.
Te perdiste uno.
Primer código de corrección, luego de claridad (¡los dos están a menudo conectados, por supuesto!). Finalmente, y solo si tiene evidencia empírica real de que realmente lo necesita, puede considerar la optimización. La optimización prematura es realmente malvada. La optimización casi siempre le cuesta tiempo, claridad y facilidad de mantenimiento. Es mejor que te asegures de comprar algo que valga la pena con eso.
Tenga en cuenta que los buenos algoritmos casi siempre superan la afinación localizada. No hay ninguna razón por la que no pueda tener un código correcto, claro y rápido. Sin embargo, serás irracionalmente afortunado si comienzas centrándote en "rápido".
Un factor que a menudo se pasa por alto en este debate es el tiempo adicional que le lleva al programador navegar, comprender y modificar el código menos legible. Considerando que el tiempo de un programador es de cien dólares por hora o más, este es un costo muy real.
Cualquier ganancia de rendimiento es contrarrestada por este costo adicional directo en el desarrollo.
Yo diría que ir por la legibilidad.
Pero en el ejemplo dado, creo que la segunda versión ya es lo suficientemente legible, ya que el nombre de la función indica exactamente qué está sucediendo en la función.
Si siempre tuviéramos funciones que nos dijeran, qué hacen ...
usando << would by a micro optimization. Entonces la regla de Hoare (no Knuts):
La optimización prematura es la raíz de todo mal.
se aplica y, en primer lugar, debe utilizar la versión más legible.
Esta es una regla que, en mi humilde opinión, a menudo se usa indebidamente como excusa para diseñar un software que nunca pueda escalar o funcionar bien.
Siempre debe optimizar al máximo, el rendimiento siempre cuenta. La razón por la que tenemos bloatware hoy, es que la mayoría de los programadores no quieren hacer el trabajo de optimización.
Habiendo dicho eso, siempre puedes poner comentarios donde la codificación resuelta necesita aclaración.