Why is the binarySearch() method in java.util.Arrays implemented using a loop?

satheesh m :

Why is the binarySearch() method in java.util.Arrays implemented using a loop and not by using recursion?

Krzysztof Atłasik :

tl;dr: Because javac doesn't do tail call optimization.

As you probably noticed many algorithms are recursive by its nature (binary search is a great example). So why recursion is not widely used in Java?

The first reason is that recursion is not as performant as plain loops. Second, a more important reason is that recursion in Java is not stack-safe. If your recursion will go to deep into the call stack it might cause the StackOverflowError. It is problematic since you can't really predict how deep you will go because it depends on the data you're processing. A consequence of this is that your recursive function may work correctly on smaller sets of data, but will blow up the stack on bigger sets.

Fortunately, every recursive function can be transformed into an iterative function by replacing recursive calls with iterative control constructs and therefore become stack-safe and this is exactly what you see in java.util.Arrays.

There's also the downside that iterative versions of algorithms might be considered to be harder to reason about and less readable (but that's debatable).

Recursion is also a way to do "loops" without mutable state (loop counter) so this way you can do purely functional iterations (for example Haskell don't even have loops, it depends only on recursion).

So can we have stack-safe, readable and performant recursion? Yes, if the compiler can optimize recursion to code very similar to loop. Most of JVM languages compilers (Groovy, Scala, Kotlin, Clojure and probably more) can do tail-call optimalization. That means is recursive call is last thing function does it will be compiled to bytecode, which looks very similar to the plain while loop.

Actually, there is proposal to add tail-call optimization to javac, but it is yet not implemented. If you want to use stack-safe recursion now, you will probably need to use some other JVM language.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=111915&siteId=1