Czym jest eliminacja rekurencji ogonowej?

Steve Yegge wspomniał o tym w poście na blogu i nie mam pojęcia co to znaczy, czy ktoś mógłby mnie wprowadzić?

Czy to to samo co optymalizacja połączeń ogonowych?

Author: Community, 2009-08-06

2 answers

Eliminacja wywołań ogonowych to optymalizacja, która oszczędza miejsce na stosie. Zastępuje ona funkcję wywołania z goto . Eliminacja rekurencji ogonowej to to samo, ale z dodanym ograniczeniem, które Funkcja sama wywołuje.

Zasadniczo, jeśli ostatnią rzeczą, jaką robi Funkcja A jest return A(params...), możesz wyeliminować alokację ramki stosu i zamiast tego ustawić odpowiednie rejestry i przejść bezpośrednio do ciała funkcji.

Rozważmy (urojona) konwencja wywołująca, która przekazuje wszystkie parametry na stosie i zwraca wartość w jakimś rejestrze.

Niektóre funkcje mogą skompilować się do (w wyimaginowanym języku asemblacji):

function:
//Reading params B, C, & D off the stack
pop B
pop C
pop D
//Do something meaningful, including a base case return
...
//Pass new values for B, C, & D to a new invocation of function on the stack
push D*
push C*
push B*
call function
ret

Cokolwiek powyższe faktycznie robi, zajmuje zupełnie nową ramkę stosu dla każdego wywołania funkcji. Ponieważ jednak po wywołaniu funkcji ogonowej nic się nie dzieje, z wyjątkiem powrotu, możemy bezpiecznie zoptymalizować ten przypadek.

W wyniku:

function:
//Reading params B, C, & D off the stack (but only on the first call)
pop B
pop C
pop D
function_tail_optimized:
//Do something meaningful, including a base case return
...
//Instead of a new stack frame, load the new values directly into the registers
load B, B*
load C, C*
load D, D*
//Don't call, instead jump directly back into the function
jump function_tail_optimized

Efektem końcowym jest równoważna funkcja, która oszczędza dużo miejsca na stosie, szczególnie dla wejść, które powodują dużą liczbę wywołań rekurencyjnych.

Moja odpowiedź wymaga dużo wyobraźni, ale myślę, że możesz to zrozumieć.
 58
Author: Kevin Montrose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-07 06:19:01

From here :

"...Eliminacja rekurencji ogonowej jest szczególny przypadek eliminacji wywołania ogonowego w którym wywołanie ogonowe jest wywołaniem do sama funkcja. W takim przypadku wywołanie można zastąpić skokiem do uruchomienie funkcji po przeniesieniu nowe argumenty do właściwego rejestry lub lokalizacje stosów..."

From Wikipedia :

"...Po wywołaniu funkcji komputer musi "zapamiętać" miejsce, w którym została wywołana from, adres zwrotny, tak, że może wrócić do tej lokalizacji z wynikiem po zakończeniu połączenia. Zazwyczaj informacje te są zapisywane na stosie, prostej liście lokalizacji zwrotnych w kolejności, w jakiej zostały osiągnięte lokalizacje połączeń, które opisują. Czasami ostatnią rzeczą, jaką robi funkcja po wykonaniu wszystkich innych operacji, jest po prostu wywołanie funkcji, ewentualnie samej siebie, i zwrócenie jej wyniku. Z rekurencją ogonową, nie ma potrzeby pamiętania miejsca, które nazywamy from-zamiast tego, możemy zostawić stos sam, a nowo wywołana funkcja zwróci swój wynik bezpośrednio do oryginalnego wywołującego. Konwersja wywołania na gałąź lub skok w takim przypadku nazywa się optymalizacją wywołania ogonowego. zauważ, że wywołanie ogonowe nie musi pojawiać się leksykalnie po wszystkich innych instrukcjach w kodzie źródłowym; ważne jest tylko, aby jego wynik został natychmiast zwrócony, ponieważ funkcja wywołująca nigdy nie będzie miała szansy cokolwiek zrobić po wywołaniu, jeśli optymalizacja jest wykonywana...."

 10
Author: pageman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-06 18:16:11