When programming with Java / kotlin, it is recommended to use tail recursive or iterative version? Is there any difference in performance?

I try to learn good habits in programming, and I stick to this problem I know that in Java, recursive functions can be "painful ass" (sometimes), and I try to implement as many tail versions of the function as possible Is it worth worrying about, or should it be done in an old-fashioned way?

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
}

Solution

The biggest difference I see is the signature: Although iterative_ Fibonacci accepts a parameter and is very clear, but tail_ Fibonacci requires three, although default values are provided, which may surprise users However, you can create a wrapper function for it and even make the tailrec function local one

Except n.minus (BigInteger. One) vs count = BigInteger In addition to one, the result bytecode of compiling two functions should not be much different. You can check it yourself with a kotlin bytecode viewer

In terms of performance, there should be no predictable difference between the two implementations (also note that the JVM uses the JIT compiler to optimize the code at runtime), but of course, the tailrec function is more effective than ordinary recursive functions

As for code style (based on high opinion), many tail recursive solutions look more natural (and closer to mathematical symbols), while others don't (for example, when many parameters end up completely confused)

Therefore, I think tailrec should be used as a performance tool when you find a recursive definition more suitable for expressing code (especially as a method to avoid stack overflow, which requires all recursive calls to be tail calls)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>