python performance algorithm optimization code-readability

python - Preservar la legibilidad del código mientras se optimiza



performance algorithm (4)

Estoy escribiendo un programa científico en Python y C con algunos algoritmos complejos de simulación física. Después de implementar el algoritmo, descubrí que hay muchas optimizaciones posibles para mejorar el rendimiento. Los comunes son precalcular valores, obtener cálculos fuera de ciclo, reemplazar algoritmos matriciales simples con otros más complejos. Pero surge un problema. El algoritmo no optimizado es mucho más lento, pero su lógica y conexión con la teoría parecen mucho más claras y legibles. Además, es más difícil extender y modificar el algoritmo optimizado.

Entonces, la pregunta es: ¿qué técnicas debo usar para mantener la legibilidad y mejorar el rendimiento? Ahora estoy tratando de mantener las ramas rápidas y claras y desarrollarlas en paralelo, pero ¿quizás hay mejores métodos?


Es común suponer que debe renunciar a la legibilidad para obtener el rendimiento.

Eso no es necesariamente así.

Necesitas descubrir qué es exactamente lo que se gasta en hacer y por qué .

Noten, no dije que debían hacer ninguna medición.

Aquí hay un ejemplo de lo que quiero decir.

Es muy probable que pueda hacer algunos cambios simples para evitar el desperdicio de movimiento, pero no arregle nada hasta que el programa le haya dicho qué debe corregir.


La suya es una muy buena pregunta que surge en casi cada pieza de código, por simple o compleja que sea la que escriba cualquier programador que quiera llamarse a sí mismo un profesional.

Trato de recordar y tener en cuenta que un lector que acaba de ingresar a mi código tiene prácticamente la misma visión cruda del problema y el mismo enfoque directo (tal vez fuerza bruta) que tuve originalmente. Luego, a medida que obtengo una comprensión más profunda del problema y los caminos hacia la solución se vuelven más claros, trato de escribir comentarios que reflejen esa mejor comprensión. A veces tengo éxito y esos comentarios ayudan a los lectores y, especialmente, me ayudan cuando vuelvo al código seis semanas después. Mi estilo es escribir muchos comentarios de todos modos y, cuando no lo hago (porque: una percepción repentina me emociona; quiero verlo funcionar; mi cerebro está frito), casi siempre lo lamento mucho más tarde.

Sería genial si pudiera mantener dos flujos de código paralelos: la forma ingenua y la forma optimizada más sofisticada. Pero nunca he tenido éxito en eso.

Para mí, la conclusión es que si puedo escribir comentarios claros, completos, concisos, precisos y actualizados, eso es lo mejor que puedo hacer.

Solo una cosa más que ya sabe: la optimización por lo general no significa cambiar una tonelada de código en una línea de origen, tal vez al llamar a una función cuyo argumento es otra función cuyo argumento es otra función cuyo argumento es otra función. Sé que algunos hacen esto para evitar almacenar temporalmente el valor de una función. Pero hace muy poco (generalmente nada) para acelerar el código y es una perra a seguir. No hay noticias para ti, lo sé.


Solo como un comentario general (no estoy muy familiarizado con Python): sugeriría que se asegure de poder intercambiar fácilmente las partes lentas de la ''implementación de referencia'' con las partes ''optimizadas'' (por ejemplo, use algo como la Strategy modelo).

Esto le permitirá validar de forma cruzada los resultados de los algoritmos más sofisticados (para asegurarse de que no arruinó los resultados) y mantendrá clara la estructura general del algoritmo de simulación ( separación de inquietudes ). Puede colocar los algoritmos optimizados en archivos / carpetas / paquetes de origen separados y documentarlos por separado, con tanto detalle como sea necesario.

Aparte de esto, intente evitar las trampas habituales : no haga una optimización prematura (verifique si realmente vale la pena, por ejemplo, con un generador de perfiles), y no reinvente la rueda (busque las bibliotecas disponibles).


def whatYouShouldDo(servings, integration_method=oven): """ Make chicken soup """ # Comments: # They are important. With some syntax highlighting, the comments are # the first thing a new programmer will look for. Therefore, they should # motivate your algorithm, outline it, and break it up into stages. # You can MAKE IT FEEL AS IF YOU ARE READING TEXT, interspersing code # amongst the text. # # Algorithm overview: # To make chicken soup, we will acquire chicken broth and some noodles. # Preprocessing ingredients is done to optimize cooking time. Then we # will output in SOUP format via stdout. # # BEGIN ALGORITHM # # Preprocessing: # 1. Thaw chicken broth. broth = chickenstore.deserialize() # 2. Mix with noodles if not noodles in cache: with begin_transaction(locals=poulty) as t: cache[noodles] = t.buy(noodles) # get from local store noodles = cache[noodles] # 3. Perform 4th-order Runge-Kutta numerical integration import kitchensink import * # FIXME: poor form, better to from kitchensink import pan at beginning result = boilerplate.RK4(broth `semidirect_product` noodles) # 4. Serve hot log.debug(''attempting to serve'') return result log.debug(''server successful'')

vea también http://en.wikipedia.org/wiki/Literate_programming#Example

También he oído que esto es lo que http://en.wikipedia.org/wiki/Aspect-oriented_programming intenta ayudar, aunque no lo he investigado realmente. (Simplemente parece ser una forma elegante de decir "coloque sus optimizaciones y sus errores y su otra basura fuera de la función que está escribiendo").