1 puntos por GN⁺ 2023-11-16 | 1 comentarios | Compartir por WhatsApp

Subir las condicionales dentro de una función

  • Si hay una condición if dentro de una función, conviene considerar moverla al llamador (caller).
  • En lugar de que la función verifique internamente las precondiciones y, si no se cumplen, “no haga nada”, se hace que el llamador verifique las precondiciones para garantizar mediante tipos que dichas precondiciones sí se cumplen.
  • En particular, “subir” las precondiciones puede reducir la cantidad total de verificaciones, y esa es una de las motivaciones de esta regla.

Bajar los bucles

  • Es una regla que surge del pensamiento orientado a datos: introduce el concepto de “batch” de un objeto, toma las operaciones por lote como caso base y trata la versión escalar como un caso especial de la versión por lote.
  • La principal ventaja es la mejora de rendimiento, ya que permite amortizar el costo de arranque y tener flexibilidad en el orden del procesamiento.
  • Por ejemplo, en la multiplicación de polinomios basada en FFT, evaluar un polinomio en varios puntos al mismo tiempo puede ser más rápido que hacer evaluaciones individuales.

Opinión de GN⁺

  • Lo más importante de este artículo son dos reglas de programación para mejorar el rendimiento y la claridad del código en el desarrollo de software: “subir las condicionales” y “bajar los bucles”.
  • Estas reglas ayudan a mejorar la legibilidad del código, optimizar el rendimiento y reducir la probabilidad de que aparezcan bugs.
  • Como ofrece ideas sobre cómo manejar la complejidad de la ingeniería de software y escribir código eficiente, este artículo resulta interesante y útil para muchos desarrolladores.

1 comentarios

 
GN⁺ 2023-11-16
Opiniones de Hacker News
  • Hay quien opina que resulta sorprendente la reacción en contra del consejo sobre diseño orientado a datos. Como la mayoría de los usuarios de los foros escriben aplicaciones web, este consejo puede parecer irrelevante. Si en el trabajo diario no necesitas pensar en la caché de instrucciones, deberías ignorar este consejo. Consultar "Typical C++ Bullshit" de Mike Acton puede ayudar a entender la importancia de este consejo.
  • Hay quien opina que a los programadores les preocupa hacer que el código se vea bonito a "pequeña escala", pero no prestan suficiente atención al diseño adecuado de toda la base de código. Si una función tiene un buen nombre, una buena interfaz, un propósito claro, está documentada adecuadamente y no abusa de los efectos secundarios, entonces no debería importar demasiado que la función sea desordenada o cómo estén colocados los if y los for.
  • Desde la perspectiva de alguien que empezó a programar en el ámbito científico, existe la opinión de que las pequeñas optimizaciones sí importan. Usar el orden incorrecto de los bucles for puede reducir el tiempo de ejecución de una simulación de 1 semana a 1 hora. Quienes vienen de ese entorno optimizan de forma instintiva el orden de los for y los if.
  • Hay quien opina que, cuando existe un "contenedor", en lugar de escribir funciones para el contenedor, se deberían escribir funciones para la "Thing" a nivel de dominio que el contenedor contiene. Esto hace que el código sea más flexible y separa con mayor claridad el dominio central de las preocupaciones de la aplicación.
  • Existe la desventaja de mover hacia arriba los if, ya que hace que las precondiciones y postcondiciones de una función dejen de ser visibles directamente en la definición de la función. En proyectos grandes, estas funciones pueden reutilizarse fuera del contexto previsto y causar errores. Usar un framework de contratos puede ser una solución, aunque obliga a escribir las condiciones dos veces: en el contrato y en el código.
  • En un ejemplo con el lenguaje Rust, se señala que su sólido sistema de tipos evita la programación defensiva que se requiere en otros lenguajes. No es deseable que un programador de C no verifique la validez de un puntero pasado a una función y termine provocando una referencia NULL. Algunos if deben estar al inicio de la función, no al final, y los errores deben propagarse correctamente.
  • Hay quien opina que parecía que el artículo llevaría a un ejemplo de código específico, pero en realidad no fue así. En lugar del ejemplo de código esperado, se presentó otro ejemplo distinto.
  • Sin el contexto adecuado, este consejo puede parecer extraño e incluso malo. Tanto los bucles for como las sentencias if son operaciones de control de flujo, por lo que algunas afirmaciones del artículo parecen no tener sentido. Las afirmaciones sobre rendimiento son las más sólidas, pero en un consejo general deberían considerarse al final.
  • Hay quien opina que no está claro si esta regla general puede aplicarse al código real. A menudo estas reglas se convierten en dogmas equivocados, y los programadores jóvenes pueden interpretarlas mal y terminar escribiendo peor código. No se puede mover el if hacia arriba cuando la condición suele depender del walrus.
  • Hay quien opina que subir el if de precondición al llamador es una idea terrible. En casos especiales puede ser buena idea, pero en general no se desea eso. En las librerías, las precondiciones deben verificarse en el límite externo para que la implementación interna pueda avanzar sin suposiciones internas. Depender de que el llamador haga la verificación anula el propósito.