なぜjava.util.ArraysのbinarySearch()メソッドは、ループを使用して実装されていますか?

satheeshメートル:

なぜされbinarySearch()た方法java.util.Arraysは、再帰を使用して、ループではなくを使用して実装しますか?

クシシュトフ・Atłasik:

TL; DR:javacは末尾呼び出しの最適化を行いませんので。

あなたはおそらく気づいたよう多くのアルゴリズムは、(バイナリ検索が良い例です)、その性質によって、再帰的です。なぜ再帰は広く、Javaで使用されていませんか?

第一の理由は、再帰が、プレーンループなどのパフォーマンスのようではないということです。第二に、より重要な理由は、Javaでの再帰が、スタック・安全ではないということです。あなたの再帰がコールスタックに深くまで行く場合、それは可能性がありますStackOverflowErrorあなたは本当にそれはあなたがしている処理データに依存しているため、あなたが行くどのように深い予測できないので、それは問題があります。この結果は、あなたの再帰関数は、データの小さいセットで正常に動作しますが、大きなセットにスタックを爆破するということです。

幸いなことに、すべての再帰関数は、反復制御構造を持つ再帰呼び出しを置き換えることにより、反復関数に変換することができ、したがって、スタックセーフとなり、これは正確にあなたが見るものであるjava.util.Arrays

アルゴリズムの反復バージョンが難しく程度の理由であると考えられ、読みにくく(しかし、議論の余地のこと)されるかもしれないという欠点もあります。

再帰が(たとえばまた、あなたが純粋に機能的な反復を行うことができ、このようので、可変状態のない「ループ」(ループカウンタ)を行う方法であるHaskellは さえループを持っていない、それが唯一の再帰によって異なります)。

だから我々は、スタック・安全読めるとパフォーマンスの再帰を持つことができますか?はい、コンパイラはループに非常によく似たコードに再帰を最適化することができます。JVM言語コンパイラ(Groovyの、スカラ、Kotlin、Clojureの、おそらくそれ以上)のほとんどは行うことができます末尾呼び出しのoptimalizationを手段は、再帰呼び出しであることを最後の機能は、それが平野whileループと非常によく似ていますバイトコードにコンパイルされますないです。

実際には、そこにある提案に末尾呼び出しの最適化を追加するjavacが、それはまだ実装されていません。あなたは今、スタック・安全な再帰を使用したい場合は、おそらくいくつかの他のJVM言語を使用する必要があります。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=222694&siteId=1
おすすめ