[解決済み】再帰はループより速いことがあるのか?
質問
ループよりも再帰の方がきれいな場合があることは知っていますし、反復よりも再帰を使うべき場合については何も聞いていませんし、それについてはすでに多くの質問があることも知っています。
私が聞きたいのは、再帰は これまで ループより速いのか?ループは常に新しいスタックフレームをセットアップする必要がないため、ループを改良して再帰的関数よりも高速に動作させることができるように思えます。
特に、ソート関数や二分木など、再帰がデータを処理する正しい方法であるアプリケーションにおいて、再帰がより速いかどうかを調べているのです。
どのように解決するのですか?
これは、使用する言語によって異なります。 言語にとらわれない」とおっしゃるので、いくつか例を挙げてみましょう。
Java、C、Pythonでは、再帰は新しいスタック・フレームの割り当てが必要なため、(一般的な)反復に比べかなり高価です。 Cコンパイラの中には、このオーバーヘッドをなくすためにコンパイラフラグを使うことができるものがあり、これによりある種の再帰(実際にはある種のテールコール)を関数呼び出しではなくジャンプに変換することができる。
関数型プログラミング言語の実装では、反復が非常に高価で、再帰が非常に安価になることがあります。 多くの場合、再帰は単純なジャンプに変換されるが、ループ変数を変更する(これはミュータブルである)。 時々 特に複数スレッドの実行をサポートする実装では、比較的重い操作が必要になります。 ミューテーターとガベージコレクタが同時に実行されている場合、ミューテーターとガベージコレクタの間の相互作用のために、これらの環境の一部でミューテーションは高価です。
Schemeの処理系によっては、一般にループよりも再帰の方が高速になることがあるのは知っています。
要するに、答えはコードと実装に依存するのです。 好きなスタイルを使えばいいのです。 関数型言語を使っているのであれば、再帰は かもしれない の方が速い。 命令型言語を使っている場合、反復は おそらく が速くなります。 環境によっては、どちらの方法でも同じアセンブリが生成されます(それをパイプに入れて吸ってください)。
追記 環境によっては、再帰でも反復でもなく、高次の関数が最適な場合もあります。 例えば、"map", "filter", "reduce" ("fold" とも呼ばれる)などである。 これらの関数は優先的に使用され、よりクリーンであるだけでなく、環境によっては自動並列化によって最初に(あるいは唯一)ブーストされるため、反復処理や再帰処理よりも大幅に速くなることがあります。 データ並列Haskellはそのような環境の一例です。
リスト内包はもう一つの選択肢ですが、これは通常、反復、再帰、高次関数のための構文上の糖分に過ぎません。
関連
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] B "の印刷が "#"の印刷より劇的に遅いのはなぜですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] 末尾再帰とは何ですか?
-
[解決済み] Bashでファイルの中身をループする
-
[解決済み] <は<=より速いのか?
-
[解決済み] \0-9]よりも効率が悪い
-
[解決済み] なぜ[]はlist()よりも速いのですか?
-
[解決済み】-depth 1でcloneを浅くし、コミットを作成し、再び更新をpullするのは安全ですか?
-
[解決済み] TeamViewerはどうしてこんなに速いのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 実行時間(高速化)の計算方法
-
[解決済み] 効率的なアウトオブコアソーティング
-
[解決済み] 末尾再帰とは何ですか?
-
[解決済み] πの値を最も早く求める方法は何ですか?
-
[解決済み】再帰と反復のどちらを選ぶ?
-
[解決済み】Goはどうしてそんなに早くコンパイルできるのですか?
-
[解決済み】長さnのソートされていない配列の中でk番目に大きい要素をO(n)で見つけるにはどうすればよいですか?)
-
[解決済み】x86_64アセンブリで無駄なMOV命令を導入すると、なぜタイトループが速くなるのでしょうか?
-
[解決済み] t-sqlのクエリ実行にかかる時間の測定
-
[解決済み] Apache Spark: map vs mapPartitions?