Ú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.
fuente
Respuestas:
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?
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 .
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).
fuente
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.
fuente
¿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.
fuente
Aj
yT0
porque esa era la forma en que las variables se nombraban en las funciones que traducía al código. Usar algo comocorrelationIndex
ostartTime
te haría quejarse.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:
Varios de los factores contribuyentes anteriores son antípodas con el desarrollo de software empresarial:
fuente
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.
fuente
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.
fuente