¿Es el código científico un reino lo suficientemente diferente como para ignorar los estándares de codificación comunes?

21

Últimamente he estado tratando de aclarar mi mente sobre el siguiente hecho.

Por un lado, hay una serie de pautas y estándares de codificación para lo que se considera código "saludable", "limpio", "bien escrito", etc. Vea el "Código limpio" que parece ser ampliamente discutido aquí también. Regla de ejemplo: 7 métodos de línea larga y 1 o 2 niveles de sangría. Se espera que el código que no sigue de alguna manera muera por falta de mantenimiento.

Por otro lado, me pongo a trabajar con OpenCV, OpenCascade, VTK, etc. Es un código científico. Tienen métodos de 2 páginas (solo yo), OpenCascade tiene un método o una clase dividida en 10 archivos (no hay bromas aquí), VTK también es un desastre a veces. ¡Sin embargo, estos proyectos prosperan, se mantienen y se usan ampliamente!

¿Dónde está la trampa? ¿Se nos permite escribir código científico y matemático de una manera que simplemente funcione y podamos mantenerlo? ¿Existe un conjunto separado de estándares para tales proyectos, si los hay?

Puede ser una pregunta ingenua, pero estoy en lo que parece ser un vacío de programación tratando de construir un conjunto de reglas sobre cómo hacer y no hacer las cosas, que es la forma en que me enseñaron a trabajar en la escuela secundaria. Desde que me gradué, casi no he tenido apoyo de guía con las cosas que he tenido que hacer, principalmente la programación, nadie se molesta en enseñar eso.

iksemyonov
fuente
25
No, no lo es, pero la mayoría de los científicos no tienen la capacitación en ingeniería para saber mejor.
Gort the Robot
44
En cualquier proyecto que haya existido por un tiempo, encontrará una tonelada de código que está mal escrito pero que parece funcionar lo suficientemente bien como para que nadie se moleste en volver y limpiarlo. A veces eso se debe a que los estándares y patrones evolucionan con el tiempo, a veces porque los estándares no se aplicaron de manera uniforme, a veces es porque es mucho más divertido agregar una nueva funcionalidad que retroceder y refactorizar un código que funciona pero está mal documentado
Justin Cave
2
@JustinCaveL O: "Si no está roto, no lo arregles". Especialmente aplicable al código de solo escritura . Ver también plaza.ufl.edu/johnaris/PDFs/ProblemSolvingFlowChart.pdf
Robert Harvey
Sin duda encontrará relevante mi pregunta anterior: programmers.stackexchange.com/q/266388/620
rwong
8
Para los demás respondedores: esta pregunta se refiere a la base de código de las bibliotecas de código abierto para tareas computacionalmente intensivas en uno o más dominios científicos . Esta pregunta no se trata de código desechable. Haga una pausa por un momento para asegurarse de comprender todos los aspectos resaltados antes de escribir una respuesta. Gracias.
rwong

Respuestas:

28

¿Es el código científico un reino lo suficientemente diferente como para ignorar los estándares de codificación comunes?

No, no es.

El código de investigación a menudo es "desechado" y escrito por personas que no son desarrolladores en segundo plano, por muy sólidas que sean sus credenciales académicas. Algunos de los códigos de investigación que escribí me harían llorar . ¡Pero funcionó!

Una cosa a considerar es que los guardianes de los proyectos conducen lo que se incluye. Si un proyecto grande comenzó como un proyecto de código académico / de investigación, termina funcionando y ahora es un desastre, alguien tiene que tomar la iniciativa para refactorizarlo.

Se necesita mucho trabajo para refactorizar el código existente que no está causando problemas. Especialmente si es un dominio específico o no tiene pruebas. Verá que OpenCV tiene una guía de estilo que es muy completa, incluso si no es perfecta. ¿Aplica esto retroactivamente a todo el código existente? Eso es ... no para los débiles de corazón.

Esto es aún más difícil si todo ese código funciona. Porque no está roto ¿Por qué arreglarlo?

¡Sin embargo, estos proyectos prosperan, se mantienen y se usan ampliamente!

Esta es la respuesta, en cierto sentido. El código de trabajo sigue siendo útil y, por lo tanto, es más probable que se mantenga.

Puede ser un desastre, especialmente al principio. Algunos de estos proyectos probablemente comenzaron como un proyecto único que "no necesitaría ser reutilizado nunca y podría desecharse".

También considere que si está implementando un algoritmo complejo, puede tener más sentido tener métodos más grandes porque usted (y otras personas familiarizadas con el lado científico) pueden comprender mejor el algoritmo conceptualmente. Mi trabajo de tesis estaba relacionado con la optimización. Tener la lógica del algoritmo principal como un método fue considerablemente más fácil de entender de lo que hubiera sido intentar separarlo. Ciertamente, violó la regla de "7 líneas por método", pero también significó que otro investigador podría mirar mi código y comprender más rápidamente mis modificaciones al algoritmo.

Si esta implementación se abstrajera y se diseñara bien, esta transparencia se perdería para los no programadores .

Para los demás respondedores: esta pregunta se refiere a la base de código de las bibliotecas de código abierto para tareas computacionalmente intensivas en uno o más dominios científicos. Esta pregunta no se trata de código desechable. Haga una pausa por un momento para asegurarse de comprender todos los aspectos resaltados antes de escribir una respuesta.

Creo que la gente a menudo tiene la idea de que todos los proyectos de código abierto comienzan como "oye, tengo una gran idea para una biblioteca que será tremendamente popular y utilizada por miles / millones de otros" y luego cada proyecto sucede así.

La realidad es que muchos proyectos se inician y mueren. Un porcentaje ridículamente pequeño de proyectos "lo hacen" al nivel de OpenCV o VTK, etc.

OpenCV comenzó como un proyecto de investigación de Intel. Wikipedia lo describe como parte de una "serie de proyectos". Su primer lanzamiento no beta fue 2006, o siete años después de su inicio. Sospecho que el objetivo inicialmente era versiones beta significativas, no un código perfecto.

Además, la "propiedad" de OpenCV ha cambiado significativamente. Esto hace que los estándares cambien, a menos que todas las partes responsables adopten exactamente los mismos estándares y los conserven durante la duración del proyecto.

También debo señalar que OpenCV existió durante varios años antes de que se publicara el Manifiesto Ágil del que se inspira el Código Limpio (y VTK casi 10). VTK se inició 17 años antes de la publicación de Clean Code (OpenCV fue "solo" 9 años antes).

Enderland
fuente
2
He estado usando OpenCV en 2004 y fue horrible. Willow Garage (nuevos propietarios ) hizo un gran trabajo al convertir casi todo en C ++. En realidad, es una de las pocas bibliotecas científicas que consta de un buen código.
nimcap
15

Los científicos no son desarrolladores. Su trabajo no es escribir código per se. Su trabajo es resolver problemas, y la programación es solo una de las herramientas que pueden usar.

La mayoría de los códigos empresariales escritos por, como se llamarían a sí mismos, desarrolladores profesionales es un desastre. La mayor parte de este código no usa patrones de diseño ni los usa incorrectamente. La mayoría de los comentarios son candidatos para TheDailyWTF . Entonces, dado que en nuestra propia industria, vemos resultados de personas cuyo trabajo es escribir código, ¿qué esperarías de las personas cuyo trabajo no es escribir programas?

¿Todas las prácticas que un desarrollador profesional real aprende durante su carrera beneficiarían a un científico? Absolutamente. ¿Sería posible para cada científico pasar de cinco a diez años de su vida aprendiendo el desarrollo de software? Probablemente no. Por lo tanto, la calidad del código es como es.

Otro factor es la cultura. Si tus pares no escriben código limpio, ¿por qué lo harías? Como a nadie le importa, no estás realmente inclinado a hacer un esfuerzo extra.

Finalmente, la mayoría del código científico tiene una vida útil relativamente corta. Usted escribe el código para una investigación específica, y cuando se realiza la investigación, no reutiliza el código. Una vez que tenga este hábito, es difícil hacer una diferencia entre las bibliotecas reutilizables, como las que cita y el código desechable.

Arseni Mourzenko
fuente
"Su trabajo no es escribir código per se. Su trabajo es resolver problemas" . Tenga en cuenta que técnicamente el trabajo de un desarrollador tampoco es escribir código. Su trabajo, al igual que el del científico, es resolver problemas. Estoy excluyendo las fábricas de software y los monos de código a quienes se les paga para mantener las sillas calientes, pero por definición tampoco les importa mucho el código limpio, por lo que no son relevantes para esta pregunta :)
Andres F.
8

¿Ignorar? No. ¿Volver a considerar y ajustar? Seguro. Una gran cantidad de código científico es matemático intensivo y de rendimiento crítico. Cosas como la sobrecarga de las llamadas a funciones en realidad pueden convertirse en un problema, por lo que puede terminar con estructuras más anidadas de lo que ve en una aplicación comercial típica. Eso no significa que deba sumergirse primero en mil micro optimizaciones. Aún debe concentrarse en elegir el algoritmo correcto y solo hacer optimizaciones cuyo efecto pueda medir.

Algunas de las diferencias son obvias y triviales. Las pautas de codificación generalmente requieren la elección de nombres de variables significativos y los nombres de una sola letra serán inmediatamente sospechosos. Una aplicación científica aún querrá nombres de variables significativos, pero a veces el nombre más significativo será una sola letra, que se refiere a una variable en una ecuación bien conocida.

Charles E. Grant
fuente
44
+1 para el comentario de nomenclatura variable. Cuando estaba en la escuela, hice algo de codificación independiente para varios departamentos, y en los departamentos de estadística y matemática me "animaron mucho" a usar nombres de variables como Ajy T0porque esa era la forma en que las variables se nombraban en las funciones que traducía al código. Usar algo como correlationIndexo startTimete haría quejarse.
TMN
4

Todas las respuestas existentes habían cubierto esta pregunta de manera integral. Sin embargo, me gustaría señalar cuál es la verdadera antípoda entre OpenCV, etc., en comparación con, por ejemplo, el código que se desarrolla de acuerdo con las buenas prácticas comerciales (Código completo, Código limpio, SOLIDO, etc.)

En general, hay muchos beneficios comerciales para que el código fuente sea KISS: "manténgalo simple, estúpido". También hay un YAGNI relacionado: "No lo vas a necesitar".

Desafortunadamente, para el software computacionalmente intensivo en los dominios científicos, el código fuente rara vez es simple o simple .


Tradicionalmente, OpenCV había sufrido una falta de generalizaciones (mucha duplicación de código para admitir diferentes opciones), mientras que VTK había sufrido generalizaciones excesivas (plantillas).

En los primeros días, ciertas partes de OpenCV se desarrollaron originalmente en C. Más tarde, OpenCV adoptó la API de C ++ que hoy conocemos. Algunos algoritmos se reescriben para aprovechar las interfaces de C ++ (clases base abstractas) y las plantillas de C ++. Otros algoritmos fueron simplemente envoltorios para el código C original. Los restos de este código se pueden encontrar dispersos en el módulo "imgproc".

OpenCV contiene mucha programación SIMD (vectorización). Hasta la fecha, la programación SIMD en C ++ todavía requiere el uso de intrínsecos (intel.com) , (arm.com) .

Los intrínsecos de SIMD se leen como lenguaje ensamblador, excepto que el compilador se encarga de asignar el registro de variables, y el compilador tiene libertad para intercambiar el orden de las instrucciones para aumentar el rendimiento. Los algoritmos escritos para usar intrínsecos SIMD tenían un alto costo de mantenimiento. Esta es la razón por la que mencioné una pregunta que hice anteriormente: el costo de mantenimiento de la base del código de programación SIMD .

Una persona que no está haciendo la programación SIMD puede ser llevada fácilmente a creer que SIMD puede encapsularse elegantemente y que la programación SIMD de bajo nivel ya no debería ser necesaria. Esto en realidad está bastante lejos de la verdad. Desafiaría a cualquiera a intentar implementar un algoritmo útil en SIMD (no fractales) y ver la dificultad de uso en estas encapsulaciones propuestas.


A continuación hay una larga lista de ideas cuando trato de analizar por qué el software computacional no puede ser KISS o YAGNI. Sin embargo, todas estas ideas son generalizaciones excesivas, y no parecen apoyar la observación anterior.

Los principales factores contribuyentes son:

  • Rendimiento del software
  • La necesidad de soportar muchas opciones de algoritmos y compensaciones
  • La necesidad de admitir muchas plataformas y compiladores de hardware diferentes
    • Esto se agrava con el problema del rendimiento del software: el rendimiento debe ser bueno para muchas plataformas y compiladores de hardware.
  • La falta de modernización continua de la base del código , debido a la falta de recursos, la falta de personas con conocimientos que puedan mejorar la calidad del código sin comprometer los otros factores, etc.
    • Los proyectos de código abierto sufren la tragedia de los bienes comunes .
    • Los proyectos de código abierto que reciben subvenciones tenían que cumplir con entregables específicos: la calidad del código generalmente no forma parte de ella.
    • En particular, incluso hay una falta de personas con conocimientos que puedan hacer o sugerir mejoras incrementales en la calidad del código . Este es el problema de los "globos oculares faltantes" : muchas personas se benefician del código, pero pocas se tomaron el tiempo de leerlo.
  • Falta histórica de compuertas de calidad de código , como revisión de código, pruebas unitarias, análisis estático, etc.
    • Para un proyecto a gran escala, estas compuertas de calidad de código no son simplemente pasos manuales: cada una requeriría una infraestructura (un sistema basado en web, un sistema de prueba unitaria, un sistema de automatización de construcción, etc.)

Varios de los factores contribuyentes anteriores son antípodas con el desarrollo de software empresarial:

  • Por lo general, el software empresarial no necesita lidiar con el mismo alto rendimiento de datos que se ve en el software computacional.
  • El software empresarial puede vincularse a un solo sistema operativo y arquitectura de computadora.
  • El software empresarial puede ser frugal al decidir qué funciones incluir. De hecho, el desarrollo de software empresarial alienta a los gerentes a decir que no a las nuevas funciones a menos que haya un buen caso de negocios.
    • Los usuarios de software empresarial interno pueden recibir capacitación para hacer las cosas de manera diferente, evitando la necesidad de realizar cambios en el código.
    • Si un software comercial pierde un cliente debido a una característica faltante, pero gana dos nuevos clientes debido a la simplicidad mejorada y la facilidad de uso (ver "La paradoja de la elección" ), en general es una ganancia neta: es una buena Lo que falta esta característica.
  • El software empresarial está respaldado por un flujo continuo de ingresos, por lo que puede permitirse gastar parte de él en la modernización continua de la base de código.
rwong
fuente
1
Estás aportando muchos puntos a la mesa que parecen irrelevantes para la pregunta.
Martin Maat
@MartinMaat Si tiene cosas positivas que agregar a esta pregunta, escriba su propia respuesta.
rwong
3

¿Es el código científico un reino lo suficientemente diferente como para ignorar los estándares de codificación comunes?

Depende de lo que llames "estándares de codificación comunes". No llamaría a los extremos de Agile "comunes". En particular, considerar que una función que tiene ocho líneas es demasiado larga o que tiene más de dos niveles de sangría como demasiado compleja son estándares ridículos en el campo de la programación numérica / científica.

Una función matriz simple por matriz de tiempo es más de siete líneas y tiene tres niveles de sangría. La función crecerá para ser considerablemente más compleja que eso si uno se preocupa por la eficiencia. Esta es una operación tan común que la eficiencia es importante. Romperlo en pedazos es exactamente lo que no quieres hacer. Una descomposición de la matriz será aún más compleja.

David Hammen
fuente
2
"Agile" no tiene nada que ver con los estándares de codificación.
Gort the Robot
@StevenBurnap: Claro que sí. Mira "Código limpio". Tiene montones de estándares de codificación.
David Hammen
1
El código limpio que tiene muchos estándares de codificación es un mal argumento. Es posible que el manifiesto Agile no tenga nada que ver con los estándares de codificación, pero Agile promueve la flexibilidad y responde a los cambios y se adhiere a los estándares de codificación o las mejores prácticas. Entonces, de una manera muy indirecta y circunspecta, ágil puede no tener nada que ver con los estándares de codificación, pero el estándar de codificación tiene mucho que ver con ágil.
Marjan Venema
1

Decidí publicar esto como una nueva respuesta porque es una perspectiva completamente diferente.

Echemos un vistazo a una muestra de código que considero "código limpio" en términos de visión por computadora y comprensión de imágenes:

https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/photo/src/seamless_cloning_impl.cpp

Para aquellos familiarizados con MATLAB y la informática científica, el código en C ++ es casi tan conciso como el código MATLAB más limpio posible.


Ahora tenemos que preguntarnos, ¿por qué no se escribe toda la base del código de la biblioteca (OpenCV en este ejemplo) con el mismo estándar que esta muestra de código?


Debemos estratificar la base de código de una gran biblioteca científica en niveles de abstracción .

En el nivel bajo , literalmente está re-implementando sumas y restas. O, literalmente, reasigna cada operación a las implementaciones más rápidas en cada plataforma.

https://github.com/opencv/opencv/blob/master/modules/core/src/hal_replacement.hpp

El nivel medio es donde encontramos el código "más sucio", dentro del cual se gasta entre el 80% y el 90% del tiempo de ejecución de la CPU. (Del mismo modo, tal vez el 80% - 90% del esfuerzo de desarrollo se gastó en el nivel medio, si contamos por separado los esfuerzos de desarrollo de software de la investigación científica).

En el nivel superior , tenemos el código más limpio, escrito por investigadores.


Se necesita una gran excelencia en la organización del código fuente para garantizar que estos niveles no se mezclen. Esto está más allá de los estándares de codificación , más tiene que ver con la administración de código abierto .

Por ejemplo, a veces se toma la decisión de dividir un proyecto de código abierto en dos. No puede hacer que estas cosas sucedan mediante confirmaciones de código.

rwong
fuente