Han pasado unos meses desde que comencé mi posición como desarrollador de software de nivel de entrada. Ahora que he superado algunas curvas de aprendizaje (por ejemplo, el lenguaje, la jerga, la sintaxis de VB y C #), estoy empezando a centrarme en temas más esotéricos, como escribir un mejor software.
Una simple pregunta que le presenté a un compañero de trabajo fue respondida con "Me estoy enfocando en las cosas equivocadas". Si bien respeto a este compañero de trabajo, no estoy de acuerdo con que sea una "cosa incorrecta" en la que centrarse.
Aquí estaba el código (en VB) y seguido de la pregunta.
Nota: La función GenerateAlert () devuelve un entero.
Dim alertID as Integer = GenerateAlert()
_errorDictionary.Add(argErrorID, NewErrorInfo(Now(), alertID))
vs ...
_errorDictionary.Add(argErrorID, New ErrorInfo(Now(), GenerateAlert()))
Originalmente escribí este último y lo reescribí con el "Dim alertID" para que a otra persona le resulte más fácil de leer. Pero aquí estaba mi preocupación y pregunta:
Si uno escribe esto con el ID de alerta débil, de hecho ocuparía más memoria; finito pero más, y ¿debería llamarse a este método muchas veces podría conducir a un problema? ¿Cómo manejará .NET este objeto AlertID? Fuera de .NET, uno debe deshacerse manualmente del objeto después de su uso (cerca del final del sub).
Quiero asegurarme de convertirme en un programador experto que no solo se base en la recolección de basura. ¿Estoy pensando demasiado en esto? ¿Me estoy centrando en las cosas equivocadas?
Respuestas:
"La optimización prematura es la raíz de todo mal (o al menos la mayor parte) en la programación". - Donald Knuth
Cuando se trata de su primer pase, simplemente escriba su código para que sea correcto y limpio. Si luego se determina que su código es crítico para el rendimiento (existen herramientas para determinar esto llamado perfiladores), puede reescribirse. Si no se determina que su código es crítico para el rendimiento, la legibilidad es mucho más importante.
¿Vale la pena profundizar en estos temas de rendimiento y optimización? Absolutamente, pero no en el dólar de su empresa si es innecesario.
fuente
Para un programa .NET promedio, sí, es pensar demasiado. Puede haber ocasiones en las que deseará llegar a los detalles de lo que está sucediendo dentro de .NET, pero esto es relativamente raro.
Una de las transiciones difíciles que tuve fue cambiar de usar C y MASM a programar en VB clásico en los años 90. Estaba acostumbrado a optimizar todo por tamaño y velocidad. Tuve que abandonar este pensamiento en su mayor parte y dejar que VB haga lo suyo para ser efectivo.
fuente
Como siempre decía mi compañero de trabajo:
En otras palabras, siempre tenga en cuenta KISS (manténgalo simple estúpido). Debido a que el exceso de ingeniería, el exceso de pensamiento de alguna lógica de código puede ser un problema para cambiar la lógica la próxima vez. Sin embargo, mantener el código limpio y simple siempre es una buena práctica .
Sin embargo, por tiempo y experiencia sabría mejor qué código huele y necesitaría optimización muy pronto.
fuente
La legibilidad es importante. En su ejemplo, sin embargo, no estoy seguro de que está realmente haciendo las cosas que más legible. GenerateAlert () tiene un buen nombre y no agrega mucho ruido. Probablemente hay mejores usos de su tiempo.
Sospecho que no. Esa es una optimización relativamente sencilla para el compilador.
El uso de una variable local como intermediario no tiene ningún impacto en el recolector de basura. Si la memoria de generación de GenerateAlert () new, entonces importará. Pero eso importará independientemente de la variable local o no.
AlertID no es un objeto. El resultado de GenerateAlert () es el objeto. AlertID es la variable, que si es una variable local es simplemente espacio asociado con el método para realizar un seguimiento de las cosas.
Esta es una pregunta de dicier que depende del contexto involucrado y la semántica de propiedad de la instancia proporcionada por GenerateAlert (). En general, cualquier cosa que haya creado la instancia debería eliminarla. Su programa probablemente se vería significativamente diferente si fuera diseñado con la gestión manual de la memoria en mente.
Un buen programador utiliza las herramientas disponibles, incluido el recolector de basura. Es mejor pensar demasiado que vivir ajeno. Puede que te estés enfocando en las cosas equivocadas, pero como estamos aquí, también podrías aprender sobre eso.
fuente
Haz que funcione, hazlo limpio, hazlo SÓLIDO, LUEGO haz que funcione tan rápido como sea necesario .
Ese debería ser el orden normal de las cosas. Su primera prioridad es hacer algo que pase las pruebas de aceptación que se salgan de los requisitos. Esta es su primera prioridad porque es la primera prioridad de su cliente; cumpliendo los requisitos funcionales dentro de los plazos de desarrollo. La siguiente prioridad es escribir código limpio y legible que sea fácil de entender y que su posteridad pueda mantener sin ningún WTF cuando sea necesario (casi nunca es una cuestión de "si"; usted o alguien después de usted TENDRÁ que ir volver y cambiar / arreglar algo). La tercera prioridad es hacer que el código se adhiera a la metodología SOLID (o GRASP si lo prefiere), que coloca el código en fragmentos modulares, reutilizables y reemplazables que nuevamente ayudan al mantenimiento (no solo pueden entender lo que hizo y por qué, pero hay líneas limpias a lo largo de las cuales puedo eliminar y reemplazar quirúrgicamente piezas de código). La última prioridad es el rendimiento; Si el código es lo suficientemente importante como para cumplir con las especificaciones de rendimiento, es casi seguro que sea lo primero correcto, limpio y SÓLIDO.
Haciéndose eco de Christopher (y Donald Knuth), "la optimización prematura es la raíz de todo mal". Además, el tipo de optimizaciones que está considerando son menores (se creará una referencia a su nuevo objeto en la pila independientemente de si le da un nombre en el código fuente o no) y de un tipo que no cause ninguna diferencia en el compilado ILLINOIS. Los nombres de las variables no se transfieren al IL, por lo que dado que está declarando la variable justo antes de su primer uso (y probablemente solo), apostaría algo de dinero a la cerveza que el IL es idéntico entre sus dos ejemplos. Entonces, su compañero de trabajo tiene 100% de razón; está buscando en el lugar equivocado si está buscando una instancia con nombre de variable vs en línea para optimizar algo.
Las micro optimizaciones en .NET casi nunca valen la pena (estoy hablando del 99,99% de los casos). En C / C ++, tal vez, SI sabes lo que estás haciendo. Cuando trabajas en un entorno .NET, ya estás lo suficientemente lejos del metal del hardware que hay una sobrecarga significativa en la ejecución del código. Por lo tanto, dado que ya se encuentra en un entorno que indica que ha renunciado a la velocidad vertiginosa y, en cambio, está buscando escribir código "correcto", si algo en un entorno .NET realmente no funciona lo suficientemente rápido, su complejidad es demasiado alto, o deberías considerar paralelizarlo. Aquí hay algunos consejos básicos a seguir para la optimización; Le garantizo que su productividad en la optimización (velocidad ganada por el tiempo dedicado) se disparará:
if(myObject != null && myObject.someProperty == 1)
), o B tome más de 9 veces más tiempo que A para evaluar (if(myObject != null && some10SecondMethodReturningBool())
).fuente
El único momento para preocuparse por la optimización desde el principio es cuando sabe que está tratando con algo que es enorme o algo que sabe que se ejecutará una gran cantidad de veces.
La definición de "enorme" obviamente varía en función de cómo son sus sistemas de destino.
fuente
Preferiría la versión de dos líneas simplemente porque es más fácil avanzar con un depurador. Una línea con varias llamadas incrustadas lo hace más difícil.
fuente