C での再帰の最適化方法には次のものがあります。 末尾呼び出し最適化 (TCO): 再帰呼び出しをループに置き換えて、スタック オーバーフローのリスクを排除します。GCC および Clang コンパイラーでサポートされています。末尾再帰除去 (TRE): すべての再帰呼び出しを完全に排除し、ループに置き換えます。MSVC など、TCO をサポートしない言語またはコンパイラーに適しています。
C 関数の再帰的実装: さまざまなコンパイラで最適化する方法
再帰は、関数がそれ自体を呼び出すことを可能にするメソッドです。これにより、簡潔なコードと効率的なアルゴリズムが可能になります。ただし、再帰を誤って使用すると、パフォーマンスの問題、特にスタック オーバーフローや実行速度の低下が発生する可能性があります。
再帰関数のパフォーマンスを最適化するために、次の方法を使用できます。
C での TCO と TRE の実装
C における TCO と TRE の実装はコンパイラによって異なります。これらの最適化をさまざまなコンパイラで実装する例を次に示します。
GCC および Clang
GCC コンパイラと Clang コンパイラは TCO をサポートします。 TCO を有効にするには、最適化レベル -O2
以上が必要です。
// GCC 和 Clang 中的尾调用递归 #include <iostream> int factorial(int n) { if (n == 0) return 1; return n * factorial(n - 1); } int main() { std::cout << factorial(5) << std::endl; return 0; }
MSVC
MSVC コンパイラは TCO をサポートしていません。再帰関数を最適化するには、TRE を使用できます。 TRE を有効にするには、最適化レベル /O2
以上が必要です。
// MSVC 中的尾递归消除 #include <iostream> int factorial(int n) { int result = 1; while (n > 0) { result *= n; n--; } return result; } int main() { std::cout << factorial(5) << std::endl; return 0; }
実践的なケース
フィボナッチ数列を計算する必要がある関数を考えてみましょう。フィボナッチ数列は、各数値が前の 2 つの数値の合計である再帰的に定義された数列です。
以下は、フィボナッチ数を計算するために TRE で最適化された C 関数です:
// TRE 优化的斐波那契数计算 int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; int a = 0, b = 1, c; while (n > 1) { c = a + b; a = b; b = c; n--; } return b; }
TRE を適用することにより、この関数のパフォーマンスが大幅に向上し、スタック オーバーフローのリスクが排除され、実行時間を計ります。
以上がC++ 関数の再帰的実装: さまざまなコンパイラで最適化する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。