Cuando se utiliza Java / Kotlin para la progtwigción, se recomienda utilizar la recursion de queue o la versión iterativa. ¿Hay alguna diferencia en el performance?

Intento aprender sobre buenas prácticas en progtwigción y estoy atascado con esta pregunta. Sé que en Java, las funciones recursivas pueden ser "un dolor en el culo" (a veces), y trato de implementar tanto como puedo la versión final de esa function. ¿Vale la pena molestarse con esto o debería hacerlo a la vieja usanza? ¿Hay alguna diferencia entre estas dos funciones (en Kotlin):

tailrec fun tail_fibonacci(n : BigInteger, fib1 : BigInteger = BigInteger.ZERO , fib2 : BigInteger = BigInteger.ONE) : BigInteger { return when(n){ BigInteger.ZERO -> fib1 else -> tail_fibonacci(n.minus(BigInteger.ONE),fib1.plus(fib2),fib1) } } fun iterative_fibonacci(n: BigInteger) : BigInteger { var count : BigInteger = BigInteger.ONE var a : BigInteger = BigInteger.ZERO var b : BigInteger = BigInteger.ONE var c : BigInteger while(count < n){ count += BigInteger.ONE c = a + b a = b b = c } return b } 

La mayor diferencia que veo son las firmas: mientras que iterative_fibonacci toma un argumento y es bastante claro, tail_fibonacci toma tres, y aunque se proporcionan los valores pnetworkingeterminados, esto podría sorprender al usuario. Sin embargo, puede crear una function de envoltura para ella e incluso hacer que la function tailrec local .

No debería haber mucha diferencia en el n.minus(BigInteger.ONE) de n.minus(BigInteger.ONE) resultante en el que se comstackn las dos funciones, a exception de n.minus(BigInteger.ONE) frente a count += BigInteger.ONE , y puede verificarlo usted mismo con un visor de n.minus(BigInteger.ONE) de n.minus(BigInteger.ONE) Kotlin .

En cuanto al performance, no debería haber ninguna diferencia pnetworkingecible entre las dos implementaciones (también tenga en count que la JVM optimiza adicionalmente el código en time de ejecución con el comstackdor JIT), pero, por supuesto, la function tailrec es mucho más eficiente que una ordinaria recursiva.

En cuanto al estilo de código (que está basado en opiniones), muchas soluciones recursivas de queue parecen más naturales (y más cercanas a la notación matemática), y otras no (por ejemplo, cuando hay muchos parameters que terminan en un lío completo).

Por lo tanto, creo que tailrec debe usar como una herramienta de performance (y especialmente como una forma de evitar el desbordamiento de la stack, que requiere que todas las llamadas recursivas sean secundarias) cuando encuentre una definición recursiva más adecuada para express lo que hace el código.

Son equivalentes en términos de performance. Kotlin optimizará la recursión en las funciones tailrec, lo que significa que es idéntica a un enfoque basado en bucle.

Si prefiere un enfoque funcional o iterativo, realmente se networkinguce a sus propias preferences (y las de su equipo, si corresponde), teniendo en count la legibilidad, la concisión y la intuición. Este juicio puede cambiar de método a método; una function podría ser más legible utilizando un enfoque funcional, donde otra podría beneficiarse de un ciclo directo.

Lo bueno de Kotlin es que admite ambos enfoques y permite a los desarrolladores usar la herramienta que necesitan para el trabajo.